office_translator/scripts/migrate_to_db.py
Sepehr 550f3516db feat: Add PostgreSQL database infrastructure
- Add SQLAlchemy models for User, Translation, ApiKey, UsageLog, PaymentHistory
- Add database connection management with PostgreSQL/SQLite support
- Add repository layer for CRUD operations
- Add Alembic migration setup with initial migration
- Update auth_service to automatically use database when DATABASE_URL is set
- Update docker-compose.yml with PostgreSQL service and Redis (non-optional)
- Add database migration script (scripts/migrate_to_db.py)
- Update .env.example with database configuration
2025-12-31 10:56:19 +01:00

161 lines
5.3 KiB
Python

"""
Migration script to move data from JSON files to database
Run this once to migrate existing users to the new database system
"""
import json
import os
import sys
from pathlib import Path
from datetime import datetime
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from database.connection import init_db, get_db_session
from database.repositories import UserRepository
from database.models import PlanType, SubscriptionStatus
def migrate_users_from_json():
"""Migrate users from JSON file to database"""
json_path = Path("data/users.json")
if not json_path.exists():
print("No users.json found, nothing to migrate")
return 0
# Initialize database
print("Initializing database tables...")
init_db()
# Load JSON data
with open(json_path, 'r') as f:
users_data = json.load(f)
print(f"Found {len(users_data)} users to migrate")
migrated = 0
skipped = 0
errors = 0
with get_db_session() as db:
repo = UserRepository(db)
for user_id, user_data in users_data.items():
try:
# Check if user already exists
existing = repo.get_by_email(user_data.get('email', ''))
if existing:
print(f" Skipping {user_data.get('email')} - already exists")
skipped += 1
continue
# Map plan string to enum
plan_str = user_data.get('plan', 'free')
try:
plan = PlanType(plan_str)
except ValueError:
plan = PlanType.FREE
# Map subscription status
status_str = user_data.get('subscription_status', 'active')
try:
status = SubscriptionStatus(status_str)
except ValueError:
status = SubscriptionStatus.ACTIVE
# Create user with original ID
from database.models import User
user = User(
id=user_id,
email=user_data.get('email', '').lower(),
name=user_data.get('name', ''),
password_hash=user_data.get('password_hash', ''),
email_verified=user_data.get('email_verified', False),
avatar_url=user_data.get('avatar_url'),
plan=plan,
subscription_status=status,
stripe_customer_id=user_data.get('stripe_customer_id'),
stripe_subscription_id=user_data.get('stripe_subscription_id'),
docs_translated_this_month=user_data.get('docs_translated_this_month', 0),
pages_translated_this_month=user_data.get('pages_translated_this_month', 0),
api_calls_this_month=user_data.get('api_calls_this_month', 0),
extra_credits=user_data.get('extra_credits', 0),
)
# Parse dates
if user_data.get('created_at'):
try:
user.created_at = datetime.fromisoformat(user_data['created_at'].replace('Z', '+00:00'))
except:
pass
if user_data.get('updated_at'):
try:
user.updated_at = datetime.fromisoformat(user_data['updated_at'].replace('Z', '+00:00'))
except:
pass
db.add(user)
db.commit()
print(f" Migrated: {user.email}")
migrated += 1
except Exception as e:
print(f" Error migrating {user_data.get('email', user_id)}: {e}")
errors += 1
db.rollback()
print(f"\nMigration complete:")
print(f" Migrated: {migrated}")
print(f" Skipped: {skipped}")
print(f" Errors: {errors}")
# Backup original file
if migrated > 0:
backup_path = json_path.with_suffix('.json.bak')
os.rename(json_path, backup_path)
print(f"\nOriginal file backed up to: {backup_path}")
return migrated
def verify_migration():
"""Verify the migration was successful"""
from database.connection import get_db_session
from database.repositories import UserRepository
with get_db_session() as db:
repo = UserRepository(db)
count = repo.count_users()
print(f"\nDatabase now contains {count} users")
# List first 5 users
users = repo.get_all_users(limit=5)
if users:
print("\nSample users:")
for user in users:
print(f" - {user.email} ({user.plan.value})")
if __name__ == "__main__":
print("=" * 50)
print("JSON to Database Migration Script")
print("=" * 50)
# Check environment
db_url = os.getenv("DATABASE_URL", "")
if db_url:
print(f"Database: PostgreSQL")
else:
print(f"Database: SQLite (development)")
print()
# Run migration
migrate_users_from_json()
# Verify
verify_migration()