86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
"""
|
|
Миграция данных из SQLite в PostgreSQL.
|
|
Запуск: python migrate_db.py
|
|
Требует настроенного PostgreSQL (см. database.py)
|
|
"""
|
|
import sys
|
|
from pathlib import Path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
from sqlalchemy import create_engine, text
|
|
from sqlalchemy.orm import sessionmaker
|
|
from database import DATABASE_URL, ASYNC_DATABASE_URL, Base, User, InventoryItem, CaseOpening, Contract
|
|
from database import Achievement, UserAchievement, ActivityFeed, UserRPU, UpgradeRPU, Upgrade, PromoCode, TransactionLog
|
|
|
|
# Sync SQLite source
|
|
SOURCE_URL = DATABASE_URL
|
|
# Sync PostgreSQL target (derive from async URL)
|
|
TARGET_URL = ASYNC_DATABASE_URL.replace("+asyncpg", "").replace("+aiosqlite", "")
|
|
|
|
if "sqlite" in SOURCE_URL:
|
|
print(f"Source: {SOURCE_URL}")
|
|
print(f"Target: {TARGET_URL}")
|
|
print("---")
|
|
else:
|
|
print("Source already PostgreSQL — nothing to migrate.")
|
|
sys.exit(0)
|
|
|
|
source_engine = create_engine(SOURCE_URL)
|
|
target_engine = create_engine(TARGET_URL, pool_pre_ping=True)
|
|
|
|
SourceSession = sessionmaker(bind=source_engine)
|
|
TargetSession = sessionmaker(bind=target_engine)
|
|
|
|
def migrate_table(model, target_session):
|
|
"""Copies all rows from source model to target model"""
|
|
source_session = SourceSession()
|
|
try:
|
|
rows = source_session.query(model).all()
|
|
if not rows:
|
|
return 0
|
|
count = 0
|
|
for row in rows:
|
|
# Detach from source session
|
|
source_session.expunge(row)
|
|
target_session.merge(row)
|
|
count += 1
|
|
target_session.commit()
|
|
return count
|
|
except Exception as e:
|
|
target_session.rollback()
|
|
print(f" ERROR: {e}")
|
|
return 0
|
|
finally:
|
|
source_session.close()
|
|
|
|
def main():
|
|
print("Creating target tables...")
|
|
Base.metadata.create_all(bind=target_engine)
|
|
|
|
target_session = TargetSession()
|
|
models = [
|
|
(User, "users"),
|
|
(UserRPU, "user_rpu"),
|
|
(UpgradeRPU, "upgrade_rpu"),
|
|
(InventoryItem, "inventory_items"),
|
|
(CaseOpening, "case_openings"),
|
|
(Contract, "contracts"),
|
|
(Achievement, "achievements"),
|
|
(UserAchievement, "user_achievements"),
|
|
(ActivityFeed, "activity_feed"),
|
|
(Upgrade, "upgrades"),
|
|
(PromoCode, "promo_codes"),
|
|
(TransactionLog, "transaction_log"),
|
|
]
|
|
|
|
for model, name in models:
|
|
print(f"Migrating {name}... ", end="", flush=True)
|
|
count = migrate_table(model, target_session)
|
|
print(f"{count} rows")
|
|
|
|
target_session.close()
|
|
print("\nMigration complete! Set ASYNC_DATABASE_URL to the PostgreSQL URL to use it.")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|