88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Migration: Rename DataSource.autoSync -> ragIndexEnabled, lastSynced -> lastIndexed.
|
|
|
|
This is a one-off migration for the RAG consent & control unification.
|
|
Safe to run multiple times (checks column existence before acting).
|
|
|
|
Usage:
|
|
python script_db_migrate_datasource_rag.py [--dry-run]
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import logging
|
|
from pathlib import Path
|
|
|
|
scriptPath = Path(__file__).resolve()
|
|
gatewayPath = scriptPath.parent.parent
|
|
sys.path.insert(0, str(gatewayPath))
|
|
os.chdir(str(gatewayPath))
|
|
|
|
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s", force=True)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
import psycopg2
|
|
from modules.shared.configuration import APP_CONFIG
|
|
|
|
|
|
def _getConnection():
|
|
return psycopg2.connect(
|
|
host=APP_CONFIG.get("DB_HOST", "localhost"),
|
|
port=int(APP_CONFIG.get("DB_PORT", "5432")),
|
|
database=APP_CONFIG.get("DB_DATABASE", "poweron_app"),
|
|
user=APP_CONFIG.get("DB_USER"),
|
|
password=APP_CONFIG.get("DB_PASSWORD_SECRET"),
|
|
)
|
|
|
|
|
|
def _columnExists(cur, table: str, column: str) -> bool:
|
|
cur.execute(
|
|
"""SELECT 1 FROM information_schema.columns
|
|
WHERE table_schema = 'public' AND table_name = %s AND column_name = %s""",
|
|
(table, column),
|
|
)
|
|
return cur.fetchone() is not None
|
|
|
|
|
|
def migrate(dryRun: bool = False):
|
|
conn = _getConnection()
|
|
conn.autocommit = False
|
|
cur = conn.cursor()
|
|
|
|
renames = [
|
|
("DataSource", "autoSync", "ragIndexEnabled"),
|
|
("DataSource", "lastSynced", "lastIndexed"),
|
|
]
|
|
|
|
executed = []
|
|
for table, oldCol, newCol in renames:
|
|
if _columnExists(cur, table, oldCol) and not _columnExists(cur, table, newCol):
|
|
sql = f'ALTER TABLE public."{table}" RENAME COLUMN "{oldCol}" TO "{newCol}";'
|
|
logger.info("EXEC: %s", sql)
|
|
if not dryRun:
|
|
cur.execute(sql)
|
|
executed.append(sql)
|
|
elif _columnExists(cur, table, newCol):
|
|
logger.info("SKIP: %s.%s already exists (migration already applied)", table, newCol)
|
|
elif not _columnExists(cur, table, oldCol):
|
|
logger.warning("SKIP: %s.%s does not exist (table schema may differ)", table, oldCol)
|
|
|
|
if not dryRun and executed:
|
|
conn.commit()
|
|
logger.info("Migration committed (%d statements)", len(executed))
|
|
elif dryRun and executed:
|
|
conn.rollback()
|
|
logger.info("DRY RUN — would execute %d statements", len(executed))
|
|
else:
|
|
logger.info("Nothing to do — schema already up to date")
|
|
|
|
cur.close()
|
|
conn.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--dry-run", action="store_true", help="Print SQL without executing")
|
|
args = parser.parse_args()
|
|
migrate(dryRun=args.dry_run)
|