-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmigrate_database.py
More file actions
79 lines (63 loc) · 2.89 KB
/
migrate_database.py
File metadata and controls
79 lines (63 loc) · 2.89 KB
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
# File: migrate_database.py
"""
Migration script to add unsubscribe_token and digest_type fields
Run this script to update existing database schema
"""
import sqlite3
import hashlib
import secrets
from datetime import datetime
import os
def migrate_database():
"""Add new fields to existing database"""
db_path = "data/users.db"
if not os.path.exists(db_path):
print("Database doesn't exist yet. No migration needed.")
return
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
try:
# Check if unsubscribe_token column exists
cursor.execute("PRAGMA table_info(users)")
columns = [column[1] for column in cursor.fetchall()]
if 'unsubscribe_token' not in columns:
print("Adding unsubscribe_token column to users table...")
cursor.execute("ALTER TABLE users ADD COLUMN unsubscribe_token TEXT")
# Generate tokens for existing users
cursor.execute("SELECT id, email FROM users WHERE unsubscribe_token IS NULL")
users = cursor.fetchall()
for user_id, email in users:
token = generate_unsubscribe_token(email)
cursor.execute(
"UPDATE users SET unsubscribe_token = ? WHERE id = ?",
(token, user_id)
)
print(f"Generated unsubscribe tokens for {len(users)} existing users")
# Check if digest_type column exists in digest_history
cursor.execute("PRAGMA table_info(digest_history)")
columns = [column[1] for column in cursor.fetchall()]
if 'digest_type' not in columns:
print("Adding digest_type column to digest_history table...")
cursor.execute("ALTER TABLE digest_history ADD COLUMN digest_type TEXT DEFAULT 'daily'")
# Update existing records
cursor.execute("UPDATE digest_history SET digest_type = 'daily' WHERE digest_type IS NULL")
print("Updated existing digest history records")
# Create unique index on unsubscribe_token if it doesn't exist
try:
cursor.execute("CREATE UNIQUE INDEX IF NOT EXISTS idx_unsubscribe_token ON users(unsubscribe_token)")
except sqlite3.OperationalError:
pass # Index might already exist
conn.commit()
print("Database migration completed successfully!")
except Exception as e:
print(f"Error during migration: {e}")
conn.rollback()
finally:
conn.close()
def generate_unsubscribe_token(email: str) -> str:
"""Generate unique unsubscribe token"""
random_part = secrets.token_hex(16)
token_data = f"{email}:{random_part}:{datetime.utcnow().isoformat()}"
return hashlib.sha256(token_data.encode()).hexdigest()[:32]
if __name__ == "__main__":
migrate_database()