Skip to content

Commit 6ff3604

Browse files
committed
Fixed check constraint handling with alternate schemas (fixes agronholm#3)
1 parent d3f2551 commit 6ff3604

2 files changed

Lines changed: 47 additions & 6 deletions

File tree

sqlacodegen/codegen.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121

2222
_re_boolean_check_constraint = re.compile(r"(?:(?:.*?)\.)?(.*?) IN \(0, 1\)")
23+
_re_column_name = re.compile(r'(?:(["`])(?:.*)\1\.)?(["`]?)(.*)\2')
2324
_re_enum_check_constraint = re.compile(r"(?:(?:.*?)\.)?(.*?) IN \((.+)\)")
2425
_re_enum_item = re.compile(r"'(.*?)(?<!\\)'")
2526

@@ -113,7 +114,7 @@ def _render_column(column, show_name):
113114
is_unique = any(isinstance(c, UniqueConstraint) and set(c.columns) == set([column])
114115
for c in column.table.constraints)
115116
has_index = any(set(i.columns) == set([column]) for i in column.table.indexes)
116-
117+
117118
# Render the column type if there are no foreign keys on it or any of them points back to itself
118119
render_coltype = not dedicated_fks or any(fk.column is column for fk in dedicated_fks)
119120

@@ -483,15 +484,15 @@ def __init__(self, metadata, noindexes=False, noconstraints=False, nojoined=Fals
483484
# Turn any integer-like column with a CheckConstraint like "column IN (0, 1)" into a Boolean
484485
match = _re_boolean_check_constraint.match(sqltext)
485486
if match:
486-
colname = match.group(1).strip('`"')
487+
colname = _re_column_name.match(match.group(1)).group(3)
487488
table.constraints.remove(constraint)
488489
table.c[colname].type = Boolean()
489490
continue
490491

491492
# Turn any string-type column with a CheckConstraint like "column IN (...)" into an Enum
492493
match = _re_enum_check_constraint.match(sqltext)
493494
if match:
494-
colname = match.group(1).strip('`"')
495+
colname = _re_column_name.match(match.group(1)).group(3)
495496
items = match.group(2)
496497
if isinstance(table.c[colname].type, String):
497498
table.constraints.remove(constraint)

test/test_codegen.py

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -820,13 +820,13 @@ class SimpleItem(Base):
820820
""")
821821

822822
def test_table_args_kwargs(self):
823-
Table(
823+
simple_items = Table(
824824
'simple_items', self.metadata,
825825
Column('id', INTEGER, primary_key=True),
826826
Column('name', VARCHAR),
827-
Index('testidx', 'id', 'name'),
828827
schema='testschema'
829828
)
829+
simple_items.indexes.add(Index('testidx', simple_items.c.id, simple_items.c.name))
830830

831831
eq_(self.generate_code(), """\
832832
# coding: utf-8
@@ -889,4 +889,44 @@ def test_foreign_key_options(self):
889889
'simple_items', metadata,
890890
Column('name', String, ForeignKey('simple_items.name', deferrable=True, initially='DEFERRED'))
891891
)
892-
""")
892+
""")
893+
894+
def test_foreign_key_schema(self):
895+
Table(
896+
'simple_items', self.metadata,
897+
Column('id', INTEGER, primary_key=True),
898+
Column('other_item_id', INTEGER),
899+
ForeignKeyConstraint(['other_item_id'], ['otherschema.other_items.id'])
900+
)
901+
Table(
902+
'other_items', self.metadata,
903+
Column('id', INTEGER, primary_key=True),
904+
schema='otherschema'
905+
)
906+
907+
eq_(self.generate_code(), """\
908+
# coding: utf-8
909+
from sqlalchemy import Column, ForeignKey, Integer
910+
from sqlalchemy.orm import relationship
911+
from sqlalchemy.ext.declarative import declarative_base
912+
913+
914+
Base = declarative_base()
915+
metadata = Base.metadata
916+
917+
918+
class SimpleItem(Base):
919+
__tablename__ = 'simple_items'
920+
921+
id = Column(Integer, primary_key=True)
922+
other_item_id = Column(ForeignKey('otherschema.other_items.id'))
923+
924+
other_item = relationship('OtherItem')
925+
926+
927+
class OtherItem(Base):
928+
__tablename__ = 'other_items'
929+
__table_args__ = {'schema': 'otherschema'}
930+
931+
id = Column(Integer, primary_key=True)
932+
""")

0 commit comments

Comments
 (0)