110 lines
3.4 KiB
Python
110 lines
3.4 KiB
Python
import sys, os
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
|
|
|
|
from app import create_app
|
|
from sqlalchemy import text
|
|
import sqlite3
|
|
|
|
SQLITE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'data', 'aufmass.db')
|
|
|
|
# Tables in FK-safe order (parents first)
|
|
TABLE_ORDER = [
|
|
'companies',
|
|
'users',
|
|
'licenses',
|
|
'contracts',
|
|
'modules',
|
|
'aufmass_typen',
|
|
'projekte',
|
|
'custom_modules',
|
|
'company_modules',
|
|
'license_modules',
|
|
'aufmass',
|
|
'lv_positionen',
|
|
'positionen',
|
|
'project_access',
|
|
'custom_module_assignments',
|
|
'user_module_permissions',
|
|
'view_profiles',
|
|
]
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("SQLite -> PostgreSQL Migration v2")
|
|
print("=" * 60)
|
|
|
|
if not os.path.exists(SQLITE_PATH):
|
|
print(f"SQLite DB nicht gefunden: {SQLITE_PATH}")
|
|
return
|
|
|
|
# Read all SQLite data
|
|
print("\n1. Lese SQLite-Daten...")
|
|
conn = sqlite3.connect(SQLITE_PATH)
|
|
conn.row_factory = sqlite3.Row
|
|
c = conn.cursor()
|
|
sqlite_data = {}
|
|
for table_name in TABLE_ORDER:
|
|
c.execute(f'SELECT * FROM "{table_name}"')
|
|
rows = [dict(r) for r in c.fetchall()]
|
|
sqlite_data[table_name] = rows
|
|
print(f" {table_name}: {len(rows)} Zeilen")
|
|
conn.close()
|
|
|
|
# Create Flask app -> creates PG tables + seed defaults
|
|
print("\n2. Starte Flask-App mit PostgreSQL...")
|
|
app = create_app()
|
|
|
|
with app.app_context():
|
|
from app import db
|
|
|
|
# Delete all existing data in reverse FK order
|
|
print(" Entferne vorhandene Daten...")
|
|
with db.engine.connect() as c:
|
|
for table_name in reversed(TABLE_ORDER):
|
|
c.execute(text(f'DELETE FROM "{table_name}"'))
|
|
c.commit()
|
|
|
|
# Import in FK-safe order
|
|
print("\n3. Importiere Daten in FK-Reihenfolge...")
|
|
meta = __import__('sqlalchemy', fromlist=['MetaData']).MetaData()
|
|
meta.reflect(bind=db.engine)
|
|
|
|
total_ok = 0
|
|
total_fail = 0
|
|
|
|
for table_name in TABLE_ORDER:
|
|
rows = sqlite_data.get(table_name, [])
|
|
if not rows:
|
|
print(f" -- {table_name}: keine Daten")
|
|
continue
|
|
|
|
table = __import__('sqlalchemy', fromlist=['Table']).Table(table_name, meta, autoload_with=db.engine)
|
|
pg_cols = {c.name for c in table.columns}
|
|
|
|
ok = 0
|
|
fail = 0
|
|
with db.engine.connect() as pg_conn:
|
|
for row in rows:
|
|
filtered = {k: v for k, v in row.items() if k in pg_cols}
|
|
try:
|
|
pg_conn.execute(table.insert().values(**filtered))
|
|
ok += 1
|
|
except Exception as e:
|
|
fail += 1
|
|
if fail <= 2:
|
|
print(f" Fehler {table_name} ID={row.get('id','?')}: {e}")
|
|
pg_conn.commit()
|
|
|
|
total_ok += ok
|
|
total_fail += fail
|
|
status = "+" if ok else " "
|
|
print(f" {status} {table_name}: {ok}/{len(rows)} OK" + (f" ({fail} Fehler)" if fail else ""))
|
|
|
|
print(f"\nErgebnis: {total_ok} Zeilen importiert" + (f", {total_fail} Fehler" if total_fail else ""))
|
|
|
|
print("\nFertig! Starte Flask-App neu -> _seed_defaults() ergaenzt Seed-Daten via Upsert.")
|
|
print("PostgreSQL ist bereit fuer AufmassWeb.")
|
|
|
|
if __name__ == '__main__':
|
|
main()
|