Skip to content

Commit 2f39cb1

Browse files
committed
Fixed missing "deferrable" and "initially" keyword arguments in ForeignKey constructs
1 parent 3ccdae4 commit 2f39cb1

2 files changed

Lines changed: 37 additions & 4 deletions

File tree

sqlacodegen/codegen.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,25 @@ def _render_column_type(coltype):
9797
return text
9898

9999

100+
def _render_fk(fk):
101+
text = "ForeignKey('%s.%s'" % (fk.column.table.name, fk.column.name)
102+
if fk.deferrable:
103+
text += ', deferrable=True'
104+
if fk.initially:
105+
text += ', initially=%r' % fk.initially
106+
return text + ')'
107+
108+
100109
def _render_column(column, show_name):
101110
kwarg = []
102111
is_sole_pk = column.primary_key and len(column.table.primary_key) == 1
103112
dedicated_fks = [c for c in column.foreign_keys if len(c.constraint.columns) == 1]
104113
is_unique = any(isinstance(c, UniqueConstraint) and set(c.columns) == set([column])
105114
for c in column.table.constraints)
106115
has_index = any(set(i.columns) == set([column]) for i in column.table.indexes)
116+
117+
# Render the column type if there are no foreign keys on it or any of them points back to itself
118+
render_coltype = not dedicated_fks or any(fk.column is column for fk in dedicated_fks)
107119

108120
if column.key != column.name:
109121
kwarg.append('key')
@@ -123,8 +135,8 @@ def _render_column(column, show_name):
123135

124136
return 'Column({0})'.format(', '.join(
125137
([repr(column.name)] if show_name else []) +
126-
([_render_column_type(column.type)] if not dedicated_fks else []) +
127-
[repr(x) for x in dedicated_fks] +
138+
([_render_column_type(column.type)] if render_coltype else []) +
139+
[_render_fk(x) for x in dedicated_fks] +
128140
[repr(x) for x in column.constraints] +
129141
['{0}={1}'.format(k, repr(getattr(column, k))) for k in kwarg]))
130142

test/test_codegen.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
from nose.tools import eq_
77
from sqlalchemy.engine import create_engine
8-
from sqlalchemy.schema import MetaData, Table, Column, CheckConstraint, UniqueConstraint, Index, ForeignKeyConstraint
8+
from sqlalchemy.schema import (MetaData, Table, Column, CheckConstraint, UniqueConstraint, Index, ForeignKey,
9+
ForeignKeyConstraint)
910
from sqlalchemy.types import INTEGER, SMALLINT, VARCHAR, NUMERIC
1011
from sqlalchemy.dialects.postgresql.base import BIGINT, DOUBLE_PRECISION, BOOLEAN, ENUM
1112
from sqlalchemy.dialects.mysql.base import TINYINT
@@ -23,7 +24,7 @@ def remove_unicode_prefixes(text):
2324
remove_unicode_prefixes = lambda text: text
2425

2526

26-
class TestCodeGenerator(object):
27+
class TestModelGenerator(object):
2728
def setup(self):
2829
self.metadata = MetaData(create_engine('sqlite:///'))
2930

@@ -868,4 +869,24 @@ def test_schema_table(self):
868869
Column('name', String),
869870
schema='testschema'
870871
)
872+
""")
873+
874+
def test_foreign_key_options(self):
875+
Table(
876+
'simple_items', self.metadata,
877+
Column('name', VARCHAR, ForeignKey('simple_items.name', deferrable=True, initially='DEFERRED'))
878+
)
879+
880+
eq_(self.generate_code(), """\
881+
# coding: utf-8
882+
from sqlalchemy import Column, ForeignKey, MetaData, String, Table
883+
884+
885+
metadata = MetaData()
886+
887+
888+
t_simple_items = Table(
889+
'simple_items', metadata,
890+
Column('name', String, ForeignKey('simple_items.name', deferrable=True, initially='DEFERRED'))
891+
)
871892
""")

0 commit comments

Comments
 (0)