mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 05:50:44 +08:00
feat(persistence): PostgreSQL assistant store, chat persist fixes, gateway scripts
- Add SQLAlchemy Core repos, pg adapter/compat, assistant_store factory, Alembic bootstrap and migration/cutover scripts. - Harden chat_message writes (NUL scrub for PG), turn_uuid on attempt failure, WS turn_runner fallbacks and gateway executed_turn_uuid init. - start_gateway: log paths, PS7 stderr handling via cmd, background stdout/stderr redirect; runtime assistant_runtime_log_dir export. - Ops: clear_all_chat_sessions with PG-only --postgresql and env-gated wipe; clear_postgres_chat_sessions.ps1. - Tests: SA repos, pg compat, persist fallback, smoke env isolation; CI and docs touch-ups. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
2b32d11f43
commit
d14e9d3596
103 changed files with 7574 additions and 1641 deletions
67
runtime/operations/scripts/cutover_sqlite_to_postgresql.sh
Normal file
67
runtime/operations/scripts/cutover_sqlite_to_postgresql.sh
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env bash
|
||||
# Backup SQLite assistant DB, optional dry-run, then import into PostgreSQL (empty schema recommended).
|
||||
#
|
||||
# Loads _local/system.env via the Python migrator (--load-system-env) so AIA_ASSISTANT_DATABASE_URL /
|
||||
# AIA_ASSISTANT_DB_PATH match the gateway. Override URL with extra args, e.g. --pg-url 'postgresql+...'
|
||||
#
|
||||
# Environment:
|
||||
# SQLITE_PATH optional; default: db_path() after load_system_env
|
||||
# BACKUP_DIR optional; default: <repo>/data/pg_cutover_backups
|
||||
# NO_BACKUP=1 skip file copy
|
||||
# SKIP_DRY_RUN=1 skip dry-run pass
|
||||
# DRY_RUN_ONLY=1 only dry-run
|
||||
#
|
||||
# Example:
|
||||
# chmod +x runtime/operations/scripts/cutover_sqlite_to_postgresql.sh
|
||||
# ./runtime/operations/scripts/cutover_sqlite_to_postgresql.sh
|
||||
# ./runtime/operations/scripts/cutover_sqlite_to_postgresql.sh --pg-url 'postgresql+psycopg://u:p@h:5432/oclaw'
|
||||
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
export PYTHONPATH="${ROOT}${PYTHONPATH:+:${PYTHONPATH}}"
|
||||
MIG="${ROOT}/runtime/operations/scripts/migrate_assistant_sqlite_to_postgresql.py"
|
||||
|
||||
resolve_sqlite() {
|
||||
if [[ -n "${SQLITE_PATH:-}" ]]; then
|
||||
printf '%s' "$SQLITE_PATH"
|
||||
return
|
||||
fi
|
||||
python -c "import os,sys; sys.path.insert(0, r'''${ROOT}'''); os.chdir(r'''${ROOT}'''); from svc.config.bootstrap_env import load_system_env; load_system_env(force=True); from svc.config.paths import db_path; print(db_path(), end='')"
|
||||
}
|
||||
|
||||
SQLITE="$(resolve_sqlite)"
|
||||
if [[ ! -f "$SQLITE" ]]; then
|
||||
echo "SQLite file not found: $SQLITE" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_DIR="${BACKUP_DIR:-${ROOT}/data/pg_cutover_backups}"
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
STAMP="$(date +%Y%m%d_%H%M%S)"
|
||||
BASE="$(basename "$SQLITE" .sqlite)"
|
||||
BAK="${BACKUP_DIR}/${BASE}_pre_pg_${STAMP}.sqlite"
|
||||
|
||||
if [[ "${NO_BACKUP:-}" != "1" ]]; then
|
||||
cp -f "$SQLITE" "$BAK"
|
||||
echo "Backup written: $BAK"
|
||||
else
|
||||
echo "NO_BACKUP=1: skipping SQLite file backup." >&2
|
||||
fi
|
||||
|
||||
COMMON=(--load-system-env --sqlite "$SQLITE")
|
||||
|
||||
if [[ "${SKIP_DRY_RUN:-}" != "1" ]]; then
|
||||
echo "=== Dry-run (row counts, no PG writes) ===" >&2
|
||||
python "$MIG" "${COMMON[@]}" "$@" --dry-run
|
||||
fi
|
||||
|
||||
if [[ "${DRY_RUN_ONLY:-}" == "1" ]]; then
|
||||
echo "DRY_RUN_ONLY=1: skipping live import." >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "=== Live import into PostgreSQL ===" >&2
|
||||
python "$MIG" "${COMMON[@]}" "$@"
|
||||
echo "" >&2
|
||||
echo "Done. Set AIA_ASSISTANT_DB_BACKEND=postgresql and AIA_ASSISTANT_DATABASE_URL, then restart the gateway." >&2
|
||||
Loading…
Add table
Add a link
Reference in a new issue