Spaces:
Sleeping
Sleeping
| #!/usr/bin/env python3 | |
| """ | |
| MongoDB to Turso Migration Script | |
| Migrates messages, mentorships, and mentorship_requests from MongoDB to Turso. | |
| Run this script once to copy existing data. | |
| Usage: | |
| cd /Users/krishna./Desktop/Projects/opentriage/ai-engine | |
| python scripts/migrate_to_turso.py | |
| """ | |
| import asyncio | |
| import logging | |
| import sys | |
| from pathlib import Path | |
| # Add parent directory to path for imports | |
| sys.path.insert(0, str(Path(__file__).parent.parent)) | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| import os | |
| import libsql_experimental as libsql | |
| # MongoDB imports | |
| from config.database import db | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s - %(levelname)s - %(message)s" | |
| ) | |
| logger = logging.getLogger(__name__) | |
| def get_turso_connection(): | |
| """Get a direct Turso connection with FK checks disabled.""" | |
| url = os.environ.get('TURSO_DATABASE_URL', '') | |
| auth_token = os.environ.get('TURSO_AUTH_TOKEN', '') | |
| conn = libsql.connect( | |
| "migration_opentriage.db", | |
| sync_url=url, | |
| auth_token=auth_token | |
| ) | |
| conn.sync() | |
| # Disable foreign key checks for migration | |
| conn.execute("PRAGMA foreign_keys = OFF") | |
| return conn | |
| async def migrate_messages(conn): | |
| """Migrate all messages from MongoDB to Turso.""" | |
| logger.info("Migrating messages...") | |
| cursor = db.messages.find({}, {"_id": 0}) | |
| messages = await cursor.to_list(length=None) | |
| success_count = 0 | |
| for msg in messages: | |
| try: | |
| timestamp = msg.get('timestamp') | |
| if timestamp and not isinstance(timestamp, str): | |
| timestamp = timestamp.isoformat() | |
| conn.execute( | |
| """ | |
| INSERT OR REPLACE INTO messages (id, sender_id, receiver_id, content, read, timestamp) | |
| VALUES (?, ?, ?, ?, ?, ?) | |
| """, | |
| ( | |
| msg.get('id'), | |
| msg.get('sender_id'), | |
| msg.get('receiver_id'), | |
| msg.get('content'), | |
| 1 if msg.get('read') else 0, | |
| timestamp | |
| ) | |
| ) | |
| conn.commit() | |
| success_count += 1 | |
| except Exception as e: | |
| logger.error(f"Failed to insert message {msg.get('id')}: {e}") | |
| logger.info(f"Migrated {success_count}/{len(messages)} messages") | |
| return success_count | |
| async def migrate_mentorships(conn): | |
| """Migrate all mentorships from MongoDB to Turso.""" | |
| logger.info("Migrating mentorships...") | |
| cursor = db.mentorships.find({}, {"_id": 0}) | |
| mentorships = await cursor.to_list(length=None) | |
| success_count = 0 | |
| for m in mentorships: | |
| try: | |
| created_at = m.get('created_at') | |
| if created_at and not isinstance(created_at, str): | |
| created_at = created_at.isoformat() | |
| conn.execute( | |
| """ | |
| INSERT OR REPLACE INTO mentorships | |
| (id, mentor_id, mentor_username, mentee_id, mentee_username, status, created_at, disconnected_at) | |
| VALUES (?, ?, ?, ?, ?, ?, ?, ?) | |
| """, | |
| ( | |
| m.get('id'), | |
| m.get('mentor_id'), | |
| m.get('mentor_username'), | |
| m.get('mentee_id'), | |
| m.get('mentee_username'), | |
| m.get('status', 'active'), | |
| created_at, | |
| m.get('disconnected_at') | |
| ) | |
| ) | |
| conn.commit() | |
| success_count += 1 | |
| except Exception as e: | |
| logger.error(f"Failed to insert mentorship {m.get('id')}: {e}") | |
| logger.info(f"Migrated {success_count}/{len(mentorships)} mentorships") | |
| return success_count | |
| async def migrate_mentorship_requests(conn): | |
| """Migrate all mentorship requests from MongoDB to Turso.""" | |
| logger.info("Migrating mentorship requests...") | |
| cursor = db.mentorship_requests.find({}, {"_id": 0}) | |
| requests = await cursor.to_list(length=None) | |
| success_count = 0 | |
| for req in requests: | |
| try: | |
| created_at = req.get('created_at') | |
| if created_at and not isinstance(created_at, str): | |
| created_at = created_at.isoformat() | |
| conn.execute( | |
| """ | |
| INSERT OR REPLACE INTO mentorship_requests | |
| (id, mentee_id, mentee_username, mentor_id, mentor_username, issue_id, message, status, created_at) | |
| VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) | |
| """, | |
| ( | |
| req.get('id'), | |
| req.get('mentee_id'), | |
| req.get('mentee_username'), | |
| req.get('mentor_id'), | |
| req.get('mentor_username'), | |
| req.get('issue_id'), | |
| req.get('message'), | |
| req.get('status', 'pending'), | |
| created_at | |
| ) | |
| ) | |
| conn.commit() | |
| success_count += 1 | |
| except Exception as e: | |
| logger.error(f"Failed to insert mentorship request {req.get('id')}: {e}") | |
| logger.info(f"Migrated {success_count}/{len(requests)} mentorship requests") | |
| return success_count | |
| async def main(): | |
| """Run the migration.""" | |
| logger.info("=" * 50) | |
| logger.info("MongoDB to Turso Migration") | |
| logger.info("=" * 50) | |
| # Get connection with FK checks disabled | |
| logger.info("Connecting to Turso (with FK checks disabled)...") | |
| conn = get_turso_connection() | |
| # Run migrations | |
| msg_count = await migrate_messages(conn) | |
| mentorship_count = await migrate_mentorships(conn) | |
| request_count = await migrate_mentorship_requests(conn) | |
| # Re-enable foreign key checks | |
| conn.execute("PRAGMA foreign_keys = ON") | |
| # Sync all changes to remote | |
| logger.info("Syncing changes to remote Turso...") | |
| conn.sync() | |
| logger.info("=" * 50) | |
| logger.info("Migration Complete!") | |
| logger.info(f" Messages: {msg_count}") | |
| logger.info(f" Mentorships: {mentorship_count}") | |
| logger.info(f" Mentorship Requests: {request_count}") | |
| logger.info("=" * 50) | |
| if __name__ == "__main__": | |
| asyncio.run(main()) | |