feat(pos): add tenant migration runner

This commit is contained in:
2026-03-31 01:32:33 +00:00
parent 4814c813c1
commit d3728789ec

98
pos/migrations/runner.py Executable file
View File

@@ -0,0 +1,98 @@
#!/usr/bin/env python3
# /home/Autopartes/pos/migrations/runner.py
"""Apply schema migrations to all tenant databases."""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from tenant_db import get_master_conn, get_tenant_conn_by_dbname
MIGRATIONS_DIR = os.path.dirname(os.path.abspath(__file__))
# Migration registry: version -> filename
MIGRATIONS = {
'v1.0': 'v1.0_initial.sql',
# Future: 'v1.1': 'v1.1_add_xyz.sql',
}
def get_all_tenants():
"""Get all tenants with their current schema version."""
conn = get_master_conn()
cur = conn.cursor()
cur.execute("""
SELECT t.id, t.db_name, t.name, COALESCE(v.version, 'v0.0') as version
FROM tenants t
LEFT JOIN tenant_schema_version v ON t.id = v.tenant_id
WHERE t.is_active = true
""")
tenants = cur.fetchall()
cur.close()
conn.close()
return tenants
def apply_migration(db_name, version):
"""Apply a single migration to a tenant DB."""
filename = MIGRATIONS[version]
filepath = os.path.join(MIGRATIONS_DIR, filename)
if not os.path.exists(filepath):
print(f" ERROR: Migration file not found: {filepath}")
return False
conn = get_tenant_conn_by_dbname(db_name)
cur = conn.cursor()
try:
with open(filepath) as f:
cur.execute(f.read())
conn.commit()
return True
except Exception as e:
conn.rollback()
print(f" ERROR: {e}")
return False
finally:
cur.close()
conn.close()
def run_migrations():
"""Apply pending migrations to all tenants."""
tenants = get_all_tenants()
sorted_versions = sorted(MIGRATIONS.keys())
print(f"Found {len(tenants)} active tenants")
print(f"Available migrations: {sorted_versions}")
for tenant_id, db_name, name, current_version in tenants:
print(f"\n[{name}] (db={db_name}, current={current_version})")
for version in sorted_versions:
if version <= current_version:
continue
print(f" Applying {version}...", end=' ')
if apply_migration(db_name, version):
# Update version in master
master_conn = get_master_conn()
master_cur = master_conn.cursor()
master_cur.execute("""
INSERT INTO tenant_schema_version (tenant_id, version)
VALUES (%s, %s)
ON CONFLICT (tenant_id) DO UPDATE SET version = %s, updated_at = NOW()
""", (tenant_id, version, version))
master_conn.commit()
master_cur.close()
master_conn.close()
print("OK")
else:
print("FAILED — stopping migrations for this tenant")
break
print("\nDone.")
if __name__ == '__main__':
run_migrations()