-
Notifications
You must be signed in to change notification settings - Fork 1
/
migrate_db.py
145 lines (117 loc) · 4.74 KB
/
migrate_db.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
"""
Database migration script for BlueSky Notify.
This script migrates data from old database locations to the new one.
"""
import os
import sqlite3
from datetime import datetime
import shutil
import sys
# Add the project root to the Python path
project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, project_root)
from src.bluesky_notify.core.database import db, init_db
from src.bluesky_notify.api.routes import app
def backup_database(src_path, backup_dir):
"""Create a backup of the database file."""
if not os.path.exists(src_path):
return None
os.makedirs(backup_dir, exist_ok=True)
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
backup_path = os.path.join(backup_dir, f'bluesky_notify_{timestamp}.db')
shutil.copy2(src_path, backup_path)
return backup_path
def migrate_data(src_path, dest_path):
"""Migrate data from source database to destination database."""
if not os.path.exists(src_path):
print(f"Source database not found: {src_path}")
return False
try:
# Connect to source database
src_conn = sqlite3.connect(src_path)
src_cur = src_conn.cursor()
# Connect to destination database
dest_conn = sqlite3.connect(dest_path)
dest_cur = dest_conn.cursor()
# Get all tables from source database
src_cur.execute("SELECT name FROM sqlite_master WHERE type='table';")
tables = src_cur.fetchall()
for table in tables:
table_name = table[0]
if table_name == 'sqlite_sequence':
continue
print(f"Migrating table: {table_name}")
# Get table data
src_cur.execute(f"SELECT * FROM {table_name}")
rows = src_cur.fetchall()
if not rows:
print(f"No data in table: {table_name}")
continue
# Get column names
src_cur.execute(f"PRAGMA table_info({table_name})")
columns = src_cur.fetchall()
column_names = [col[1] for col in columns]
# Prepare insert statement
placeholders = ','.join(['?' for _ in column_names])
insert_sql = f"INSERT OR IGNORE INTO {table_name} ({','.join(column_names)}) VALUES ({placeholders})"
# Insert data
for row in rows:
try:
dest_cur.execute(insert_sql, row)
except sqlite3.IntegrityError as e:
print(f"Skipping duplicate record in {table_name}: {e}")
except Exception as e:
print(f"Error inserting row in {table_name}: {e}")
continue
# Commit changes
dest_conn.commit()
# Close connections
src_conn.close()
dest_conn.close()
return True
except Exception as e:
print(f"Error migrating database: {e}")
return False
def main():
# Define paths
project_root = os.path.dirname(os.path.abspath(__file__))
old_paths = [
os.path.join(project_root, 'bluesky_notify.db'),
os.path.join(project_root, 'src', 'instance', 'bluesky_notify.db'),
os.path.join(project_root, 'src', 'data', 'bluesky_notify.db')
]
# New database location
data_dir = os.path.join(project_root, 'data')
new_db_path = os.path.join(data_dir, 'bluesky_notify.db')
os.makedirs(data_dir, exist_ok=True)
# Initialize the new database
print("Initializing new database...")
app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{new_db_path}'
db.init_app(app)
with app.app_context():
db.create_all()
print("Database tables created successfully")
# Create backups directory
backup_dir = os.path.join(project_root, 'data', 'backups')
# Process each old database
for old_path in old_paths:
if os.path.exists(old_path) and old_path != new_db_path:
print(f"\nProcessing database: {old_path}")
# Create backup
backup_path = backup_database(old_path, backup_dir)
if backup_path:
print(f"Created backup at: {backup_path}")
# Migrate data
if migrate_data(old_path, new_db_path):
print(f"Successfully migrated data from: {old_path}")
try:
# Rename old database to .old
old_backup = old_path + '.old'
os.rename(old_path, old_backup)
print(f"Renamed old database to: {old_backup}")
except Exception as e:
print(f"Error renaming old database: {e}")
else:
print(f"Failed to migrate data from: {old_path}")
if __name__ == '__main__':
main()