-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathupdate_pkey_seqs.py
76 lines (58 loc) · 2.58 KB
/
update_pkey_seqs.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
"""
A non-class-specific way to update postgresql's autoincrementing primary key
sequences, useful for running after data including primary key values has been
seeded.
Similar to set_val_user_id() from Ratings, but works on all classes in
model.py.
Author: Katie Byers
"""
from sqlalchemy import func
from sqlalchemy.inspection import inspect
from model import db
def update_pkey_seqs():
"""Set primary key for each table to start at one higher than the current
highest key. Helps when data has been manually seeded."""
# get a dictionary of {classname: class} for all classes in model.py
model_classes = db.Model._decl_class_registry
# loop over the classes
for class_name in model_classes:
# the dictionary will include a helper class we don't care about, so
# skip it
if class_name == "_sa_module_registry":
continue
# print("-" * 40)
# print("Working on class", class_name)
# get the class itself out of the dictionary
cls = model_classes[class_name]
# get the name of the table associated with the class and its primary
# key
table_name = cls.__tablename__
pkey_column = inspect(cls).primary_key[0]
primary_key = pkey_column.name
# print("Table name:", table_name, "Primary key:", primary_key)
# check to see if the primary key is an integer (which are
# autoincrementing by default)
# if it isn't, skip to the next class
if (not isinstance(pkey_column.type, db.Integer) or
pkey_column.autoincrement is not True):
# print("Not an autoincrementing integer key - skipping.")
continue
# now we know we're dealing with an autoincrementing key, so get the
# highest id value currently in the table
result = db.session.query(func.max(getattr(cls, primary_key))).first()
# if the table is empty, result will be none; only proceed if it's not
# (we have to index at 0 since the result comes back as a tuple)
if result[0]:
# cast the result to an int
max_id = int(result[0])
# print("highest id:", max_id)
# set the next value to be max + 1
query = ("SELECT setval('" + table_name + "_" + primary_key +
"_seq', :new_id)")
db.session.execute(query, {'new_id': max_id + 1})
db.session.commit()
# print("Primary key sequence updated.")
# else:
# print("No records found. No update made.")
# we're done!
# print("-" * 40)