|
9 | 9 |
|
10 | 10 | from sqlalchemy import (Enum, ForeignKeyConstraint, PrimaryKeyConstraint, CheckConstraint, UniqueConstraint, Table, |
11 | 11 | Column) |
| 12 | +from sqlalchemy.schema import ForeignKey |
12 | 13 | from sqlalchemy.util import OrderedDict |
13 | 14 | from sqlalchemy.types import Boolean, String |
14 | 15 | import sqlalchemy |
@@ -109,15 +110,6 @@ def _render_column_type(coltype): |
109 | 110 | return text |
110 | 111 |
|
111 | 112 |
|
112 | | -def _render_fk(fk): |
113 | | - text = "ForeignKey('%s.%s'" % (fk.column.table.fullname, fk.column.name) |
114 | | - if fk.deferrable: |
115 | | - text += ', deferrable=True' |
116 | | - if fk.initially: |
117 | | - text += ', initially=%r' % fk.initially |
118 | | - return text + ')' |
119 | | - |
120 | | - |
121 | 113 | def _render_column(column, show_name): |
122 | 114 | kwarg = [] |
123 | 115 | is_sole_pk = column.primary_key and len(column.table.primary_key) == 1 |
@@ -149,17 +141,29 @@ def _render_column(column, show_name): |
149 | 141 | return 'Column({0})'.format(', '.join( |
150 | 142 | ([repr(column.name)] if show_name else []) + |
151 | 143 | ([_render_column_type(column.type)] if render_coltype else []) + |
152 | | - [_render_fk(x) for x in dedicated_fks] + |
| 144 | + [_render_constraint(x) for x in dedicated_fks] + |
153 | 145 | [repr(x) for x in column.constraints] + |
154 | 146 | ['{0}={1}'.format(k, repr(getattr(column, k))) for k in kwarg])) |
155 | 147 |
|
156 | 148 |
|
157 | 149 | def _render_constraint(constraint): |
158 | | - if isinstance(constraint, ForeignKeyConstraint): |
| 150 | + def render_fk_options(*opts): |
| 151 | + opts = [repr(opt) for opt in opts] |
| 152 | + for attr in 'ondelete', 'onupdate', 'deferrable', 'initially', 'match': |
| 153 | + value = getattr(constraint, attr) |
| 154 | + if value: |
| 155 | + opts.append('{0}={1!r}'.format(attr, value)) |
| 156 | + |
| 157 | + return ', '.join(opts) |
| 158 | + |
| 159 | + if isinstance(constraint, ForeignKey): |
| 160 | + remote_column = '{0}.{1}'.format(constraint.column.table.fullname, constraint.column.name) |
| 161 | + return 'ForeignKey({0})'.format(render_fk_options(remote_column)) |
| 162 | + elif isinstance(constraint, ForeignKeyConstraint): |
159 | 163 | local_columns = constraint.columns |
160 | 164 | remote_columns = ['{0}.{1}'.format(fk.column.table.fullname, fk.column.name) |
161 | 165 | for fk in constraint.elements] |
162 | | - return 'ForeignKeyConstraint({0!r}, {1!r})'.format(local_columns, remote_columns) |
| 166 | + return 'ForeignKeyConstraint({0})'.format(render_fk_options(local_columns, remote_columns)) |
163 | 167 | elif isinstance(constraint, CheckConstraint): |
164 | 168 | return 'CheckConstraint({0!r})'.format(_get_compiled_expression(constraint.sqltext)) |
165 | 169 | elif isinstance(constraint, UniqueConstraint): |
@@ -465,7 +469,7 @@ def __init__(self, metadata, noindexes=False, noconstraints=False, nojoined=Fals |
465 | 469 | for table in metadata.tables.values(): |
466 | 470 | # Link tables have exactly two foreign key constraints and all columns are involved in them |
467 | 471 | fk_constraints = [constr for constr in table.constraints if isinstance(constr, ForeignKeyConstraint)] |
468 | | - if (len(fk_constraints) == 2 and all(col.foreign_keys for col in table.columns)): |
| 472 | + if len(fk_constraints) == 2 and all(col.foreign_keys for col in table.columns): |
469 | 473 | association_tables.add(table.name) |
470 | 474 | tablename = sorted(fk_constraints, key=_get_constraint_sort_key)[0].elements[0].column.table.name |
471 | 475 | links[tablename].append(table) |
|
0 commit comments