You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.7 KiB
Python

#!/usr/bin/env python
# backend/scripts/migrate-sqlite-to-postgres.py — SQLite → Postgres 데이터 이관(행 수 일치 검증)
# 사용: SQLITE_URL=sqlite:////data/ari.db PG_URL=postgresql+psycopg://ari:pw@db/ari python -m scripts.migrate-sqlite-to-postgres
import os
import sys
from sqlmodel import Session, SQLModel, create_engine, select
# 모든 테이블 메타데이터 로드
import app.models # noqa: F401
def main() -> int:
src_url = os.environ.get("SQLITE_URL", "sqlite:////data/ari.db")
dst_url = os.environ["PG_URL"]
src = create_engine(src_url)
dst = create_engine(dst_url)
SQLModel.metadata.create_all(dst) # 대상 스키마 생성(또는 alembic upgrade head 선행)
mismatches = []
with Session(src) as s_src, Session(dst) as s_dst:
for table in SQLModel.metadata.sorted_tables:
model = _model_for(table.name)
if model is None:
continue
rows = s_src.exec(select(model)).all()
for r in rows:
s_dst.merge(model(**r.model_dump()))
s_dst.commit()
n_src = len(rows)
n_dst = len(s_dst.exec(select(model)).all())
print(f"{table.name}: src={n_src} dst={n_dst}")
if n_src != n_dst:
mismatches.append(table.name)
if mismatches:
print("행 수 불일치:", mismatches, file=sys.stderr)
return 1
print("이관 완료 — 행 수 일치")
return 0
def _model_for(tablename: str):
for cls in SQLModel.__subclasses__():
if getattr(cls, "__tablename__", None) == tablename:
return cls
return None
if __name__ == "__main__":
raise SystemExit(main())