mirror of
https://github.com/hansjone/oclaw.git
synced 2026-10-09 04:40:45 +08:00
- 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>
67 lines
2.4 KiB
Bash
67 lines
2.4 KiB
Bash
#!/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
|