|
14 | 14 |
|
15 | 15 | import re
|
16 | 16 |
|
17 |
| -from sqlalchemy import types |
| 17 | +from sqlalchemy import types, ForeignKeyConstraint |
18 | 18 | from sqlalchemy.engine.base import Engine
|
19 | 19 | from sqlalchemy.engine.default import DefaultDialect
|
20 | 20 | from sqlalchemy.sql.compiler import (
|
@@ -86,6 +86,36 @@ def visit_empty_set_expr(self, type_):
|
86 | 86 | class SpannerDDLCompiler(DDLCompiler):
|
87 | 87 | """Spanner DDL statements compiler."""
|
88 | 88 |
|
| 89 | + def visit_drop_table(self, drop_table): |
| 90 | + """ |
| 91 | + Cloud Spanner doesn't drop tables which have indexes |
| 92 | + or foreign key constraints. This method builds several DDL |
| 93 | + statements separated by semicolons to drop the indexes and |
| 94 | + foreign keys constraints of the table before the DROP TABLE |
| 95 | + statement. |
| 96 | +
|
| 97 | + Args: |
| 98 | + (sqlalchemy.schema.DropTable): DROP TABLE statement object. |
| 99 | +
|
| 100 | + Returns: |
| 101 | + str: |
| 102 | + DDL statements separated by semicolons, which will |
| 103 | + sequentially drop indexes, foreign keys constraints |
| 104 | + and then the table itself. |
| 105 | + """ |
| 106 | + constrs = "" |
| 107 | + for cons in drop_table.element.constraints: |
| 108 | + if isinstance(cons, ForeignKeyConstraint) and cons.name: |
| 109 | + constrs += "ALTER TABLE {table} DROP CONSTRAINT {constr};".format( |
| 110 | + table=drop_table.element.name, constr=cons.name |
| 111 | + ) |
| 112 | + |
| 113 | + indexes = "" |
| 114 | + for index in drop_table.element.indexes: |
| 115 | + indexes += "DROP INDEX {};".format(index.name) |
| 116 | + |
| 117 | + return indexes + constrs + str(drop_table) |
| 118 | + |
89 | 119 | def visit_primary_key_constraint(self, constraint):
|
90 | 120 | """Build primary key definition.
|
91 | 121 |
|
|
0 commit comments