-
Notifications
You must be signed in to change notification settings - Fork 230
/
Copy pathmigrate_database.py
executable file
·96 lines (76 loc) · 2.86 KB
/
migrate_database.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
#!/usr/bin/env python3
import argparse
import sqlite3
import uuid
import config
def upgrade(cur):
# Generate uniquifiers for already existing users
cur.execute('ALTER TABLE user ADD COLUMN fs_uniquifier VARCHAR(64)')
users = [row[0] for row in cur.execute('SELECT id FROM user')]
for uid in users:
cur.execute('UPDATE user SET fs_uniquifier = ? WHERE user.id = ?', (uuid.uuid4().hex, uid))
# Due to limitations in SQLite we have to create a temporary table
# We can't use ALTER TABLE to change fs_uniquifier from beeing NULLable to
# NOT NULL
cur.execute(
"""
CREATE TABLE "user_tmp" (
"id" INTEGER NOT NULL,
"api_key" VARCHAR(255) UNIQUE,
"email" VARCHAR(255) UNIQUE,
"password" VARCHAR(255),
"active" BOOLEAN,
"confirmed_at" DATETIME,
"fs_uniquifier" VARCHAR(64) NOT NULL UNIQUE,
CHECK(active IN (0,1)),
PRIMARY KEY("id")
);"""
)
cur.execute('INSERT INTO "user_tmp" SELECT * FROM "user" WHERE true')
cur.execute('DROP TABLE "user"')
cur.execute('ALTER TABLE "user_tmp" RENAME TO "user"')
print('Successfully upgraded the database')
def downgrade(cur):
# Due to limitations in SQLite we have to create a temporary table
# We can't DROP COLUMN fs_uniquifier because it is unique
cur.execute(
"""
CREATE TABLE "user_tmp" (
"id" INTEGER NOT NULL,
"api_key" VARCHAR(255) UNIQUE,
"email" VARCHAR(255) UNIQUE,
"password" VARCHAR(255),
"active" BOOLEAN,
"confirmed_at" DATETIME,
CHECK(active IN (0,1)),
PRIMARY KEY("id")
);"""
)
cur.execute(
'INSERT INTO "user_tmp" SELECT id, api_key, email, password, active, confirmed_at FROM "user" WHERE true'
)
cur.execute('DROP TABLE "user"')
cur.execute('ALTER TABLE "user_tmp" RENAME TO "user"')
print('Successfully downgraded the database')
def main():
parser = argparse.ArgumentParser()
parser.set_defaults(func=lambda _: parser.print_usage())
subparsers = parser.add_subparsers()
upgrade_process = subparsers.add_parser(
'upgrade', help='Upgrade the user database', formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
upgrade_process.set_defaults(func=upgrade)
downgrade_process = subparsers.add_parser(
'downgrade', help='Downgrade the user database', formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
downgrade_process.set_defaults(func=downgrade)
args = parser.parse_args()
config.load()
db_path = config.frontend.authentication.user_database[len('sqlite:///') :]
conn = sqlite3.connect(db_path)
cur = conn.cursor()
args.func(cur)
conn.commit()
conn.close()
if __name__ == '__main__':
main()