Show More
@@ -30,8 +30,24 b' class SQLiteCommon(object):' | |||
|
30 | 30 | |
|
31 | 31 | class SQLiteHelper(SQLiteCommon): |
|
32 | 32 | |
|
33 |
def _ |
|
|
34 | """Retrieve information about existing unique constraints of the table | |
|
33 | def _filter_columns(self, cols, table): | |
|
34 | """Splits the string of columns and returns those only in the table. | |
|
35 | ||
|
36 | :param cols: comma-delimited string of table columns | |
|
37 | :param table: the table to check | |
|
38 | :return: list of columns in the table | |
|
39 | """ | |
|
40 | columns = [] | |
|
41 | for c in cols.split(","): | |
|
42 | if c in table.columns: | |
|
43 | # There was a bug in reflection of SQLite columns with | |
|
44 | # reserved identifiers as names (SQLite can return them | |
|
45 | # wrapped with double quotes), so strip double quotes. | |
|
46 | columns.extend(c.strip(' "')) | |
|
47 | return columns | |
|
48 | ||
|
49 | def _get_constraints(self, table): | |
|
50 | """Retrieve information about existing constraints of the table | |
|
35 | 51 | |
|
36 | 52 | This feature is needed for recreate_table() to work properly. |
|
37 | 53 | """ |
@@ -49,19 +65,21 b' class SQLiteHelper(SQLiteCommon):' | |||
|
49 | 65 | constraints = [] |
|
50 | 66 | for name, cols in re.findall(UNIQUE_PATTERN, data): |
|
51 | 67 | # Filter out any columns that were dropped from the table. |
|
52 | columns = [] | |
|
53 | for c in cols.split(","): | |
|
54 | if c in table.columns: | |
|
55 | # There was a bug in reflection of SQLite columns with | |
|
56 | # reserved identifiers as names (SQLite can return them | |
|
57 | # wrapped with double quotes), so strip double quotes. | |
|
58 | columns.extend(c.strip(' "')) | |
|
68 | columns = self._filter_columns(cols, table) | |
|
59 | 69 | if columns: |
|
60 | 70 | constraints.extend(UniqueConstraint(*columns, name=name)) |
|
71 | ||
|
72 | FKEY_PATTERN = "CONSTRAINT (\w+) FOREIGN KEY \(([^\)]+)\)" | |
|
73 | for name, cols in re.findall(FKEY_PATTERN, data): | |
|
74 | # Filter out any columns that were dropped from the table. | |
|
75 | columns = self._filter_columns(cols, table) | |
|
76 | if columns: | |
|
77 | constraints.extend(ForeignKeyConstraint(*columns, name=name)) | |
|
78 | ||
|
61 | 79 | return constraints |
|
62 | 80 | |
|
63 | 81 | def recreate_table(self, table, column=None, delta=None, |
|
64 |
omit_ |
|
|
82 | omit_constraints=None): | |
|
65 | 83 | table_name = self.preparer.format_table(table) |
|
66 | 84 | |
|
67 | 85 | # we remove all indexes so as not to have |
@@ -69,24 +87,27 b' class SQLiteHelper(SQLiteCommon):' | |||
|
69 | 87 | for index in table.indexes: |
|
70 | 88 | index.drop() |
|
71 | 89 | |
|
72 |
# reflect existing |
|
|
73 |
for |
|
|
74 |
table.append_constraint( |
|
|
75 |
# omit given |
|
|
90 | # reflect existing constraints | |
|
91 | for constraint in self._get_constraints(table): | |
|
92 | table.append_constraint(constraint) | |
|
93 | # omit given constraints when creating a new table if required | |
|
76 | 94 | table.constraints = set([ |
|
77 | 95 | cons for cons in table.constraints |
|
78 |
if omit_ |
|
|
96 | if omit_constraints is None or cons.name not in omit_constraints | |
|
79 | 97 | ]) |
|
80 | tup = sqlite3.sqlite_version_info | |
|
81 | if tup[0] > 3 or (tup[0] == 3 and tup[1] >= 26): | |
|
98 | ||
|
99 | # Use "PRAGMA legacy_alter_table = ON" with sqlite >= 3.26 when | |
|
100 | # using "ALTER TABLE RENAME TO migration_tmp" to maintain legacy | |
|
101 | # behavior. See: https://www.sqlite.org/src/info/ae9638e9c0ad0c36 | |
|
102 | if self.connection.engine.dialect.server_version_info >= (3, 26): | |
|
82 | 103 | self.append('PRAGMA legacy_alter_table = ON') |
|
83 | 104 | self.execute() |
|
84 | ||
|
85 | 105 | self.append('ALTER TABLE %s RENAME TO migration_tmp' % table_name) |
|
86 | 106 | self.execute() |
|
87 | if tup[0] > 3 or (tup[0] == 3 and tup[1] >= 26): | |
|
107 | if self.connection.engine.dialect.server_version_info >= (3, 26): | |
|
88 | 108 | self.append('PRAGMA legacy_alter_table = OFF') |
|
89 | 109 | self.execute() |
|
110 | ||
|
90 | 111 | insertion_string = self._modify_table(table, column, delta) |
|
91 | 112 | |
|
92 | 113 | table.create(bind=self.connection) |
@@ -102,7 +123,6 b' class SQLiteHelper(SQLiteCommon):' | |||
|
102 | 123 | else: |
|
103 | 124 | column = delta |
|
104 | 125 | table = self._to_table(column.table) |
|
105 | ||
|
106 | 126 | self.recreate_table(table,column,delta) |
|
107 | 127 | |
|
108 | 128 | class SQLiteColumnGenerator(SQLiteSchemaGenerator, |
@@ -190,13 +210,14 b' class SQLiteConstraintDropper(ansisql.AN' | |||
|
190 | 210 | self.execute() |
|
191 | 211 | |
|
192 | 212 | def visit_migrate_foreign_key_constraint(self, *p, **k): |
|
193 | self._not_supported('ALTER TABLE DROP CONSTRAINT') | |
|
213 | #self._not_supported('ALTER TABLE DROP CONSTRAINT') | |
|
214 | self.recreate_table(p[0].table, omit_constraints=[p[0].name]) | |
|
194 | 215 | |
|
195 | 216 | def visit_migrate_check_constraint(self, *p, **k): |
|
196 | 217 | self._not_supported('ALTER TABLE DROP CONSTRAINT') |
|
197 | 218 | |
|
198 | 219 | def visit_migrate_unique_constraint(self, *p, **k): |
|
199 |
self.recreate_table(p[0].table, omit_ |
|
|
220 | self.recreate_table(p[0].table, omit_constraints=[p[0].name]) | |
|
200 | 221 | |
|
201 | 222 | |
|
202 | 223 | # TODO: technically primary key is a NOT NULL + UNIQUE constraint, should add NOT NULL to index |
@@ -367,8 +367,14 b' class ColumnDelta(DictMixin, sqlalchemy.' | |||
|
367 | 367 | self.process_column(self.result_column) |
|
368 | 368 | |
|
369 | 369 | # create an instance of class type if not yet |
|
370 | if 'type' in diffs and callable(self.result_column.type): | |
|
371 |
self.result_column.type |
|
|
370 | if 'type' in diffs: | |
|
371 | if callable(self.result_column.type): | |
|
372 | self.result_column.type = self.result_column.type() | |
|
373 | if self.result_column.autoincrement and \ | |
|
374 | not issubclass( | |
|
375 | self.result_column.type._type_affinity, | |
|
376 | sqlalchemy.Integer): | |
|
377 | self.result_column.autoincrement = False | |
|
372 | 378 | |
|
373 | 379 | # add column to the table |
|
374 | 380 | if self.table is not None and self.alter_metadata: |
General Comments 0
You need to be logged in to leave comments.
Login now