Skip to content

Commit 22b63d4

Browse files
Fixed named ForeignKeyConstraints (#189)
1 parent ab0353f commit 22b63d4

File tree

2 files changed

+106
-1
lines changed

2 files changed

+106
-1
lines changed

src/sqlacodegen/generators.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,9 @@ def render_column(self, column: Column[Any], show_name: bool) -> str:
347347
dedicated_fks = [
348348
c
349349
for c in column.foreign_keys
350-
if c.constraint and len(c.constraint.columns) == 1
350+
if c.constraint
351+
and len(c.constraint.columns) == 1
352+
and uses_default_name(c.constraint)
351353
]
352354
is_unique = any(
353355
isinstance(c, UniqueConstraint)

tests/test_generators.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,6 +2094,52 @@ class Simple(Base):
20942094
""",
20952095
)
20962096

2097+
def test_named_foreign_key_constraints(self, generator: CodeGenerator) -> None:
2098+
Table(
2099+
"simple_items",
2100+
generator.metadata,
2101+
Column("id", INTEGER, primary_key=True),
2102+
Column("container_id", INTEGER),
2103+
ForeignKeyConstraint(
2104+
["container_id"], ["simple_containers.id"], name="foreignkeytest"
2105+
),
2106+
)
2107+
Table(
2108+
"simple_containers",
2109+
generator.metadata,
2110+
Column("id", INTEGER, primary_key=True),
2111+
)
2112+
2113+
validate_code(
2114+
generator.generate(),
2115+
"""\
2116+
from sqlalchemy import Column, ForeignKeyConstraint, Integer
2117+
from sqlalchemy.orm import declarative_base, relationship
2118+
2119+
Base = declarative_base()
2120+
2121+
2122+
class SimpleContainers(Base):
2123+
__tablename__ = 'simple_containers'
2124+
2125+
id = Column(Integer, primary_key=True)
2126+
2127+
simple_items = relationship('SimpleItems', back_populates='container')
2128+
2129+
2130+
class SimpleItems(Base):
2131+
__tablename__ = 'simple_items'
2132+
__table_args__ = (
2133+
ForeignKeyConstraint(['container_id'], ['simple_containers.id'], name='foreignkeytest'),
2134+
)
2135+
2136+
id = Column(Integer, primary_key=True)
2137+
container_id = Column(Integer)
2138+
2139+
container = relationship('SimpleContainers', back_populates='simple_items')
2140+
""",
2141+
)
2142+
20972143

20982144
class TestDataclassGenerator:
20992145
@pytest.fixture
@@ -2290,3 +2336,60 @@ class SimpleItems:
22902336
)
22912337
""",
22922338
)
2339+
2340+
def test_named_foreign_key_constraints(self, generator: CodeGenerator) -> None:
2341+
Table(
2342+
"simple_items",
2343+
generator.metadata,
2344+
Column("id", INTEGER, primary_key=True),
2345+
Column("container_id", INTEGER),
2346+
ForeignKeyConstraint(
2347+
["container_id"], ["simple_containers.id"], name="foreignkeytest"
2348+
),
2349+
)
2350+
Table(
2351+
"simple_containers",
2352+
generator.metadata,
2353+
Column("id", INTEGER, primary_key=True),
2354+
)
2355+
2356+
validate_code(
2357+
generator.generate(),
2358+
"""\
2359+
from __future__ import annotations
2360+
2361+
from dataclasses import dataclass, field
2362+
from typing import List, Optional
2363+
2364+
from sqlalchemy import Column, ForeignKeyConstraint, Integer
2365+
from sqlalchemy.orm import registry, relationship
2366+
2367+
mapper_registry = registry()
2368+
2369+
2370+
@mapper_registry.mapped
2371+
@dataclass
2372+
class SimpleContainers:
2373+
__tablename__ = 'simple_containers'
2374+
__sa_dataclass_metadata_key__ = 'sa'
2375+
2376+
id: int = field(init=False, metadata={'sa': Column(Integer, primary_key=True)})
2377+
2378+
simple_items: List[SimpleItems] = field(default_factory=list, metadata={'sa': relationship('SimpleItems', back_populates='container')})
2379+
2380+
2381+
@mapper_registry.mapped
2382+
@dataclass
2383+
class SimpleItems:
2384+
__tablename__ = 'simple_items'
2385+
__table_args__ = (
2386+
ForeignKeyConstraint(['container_id'], ['simple_containers.id'], name='foreignkeytest'),
2387+
)
2388+
__sa_dataclass_metadata_key__ = 'sa'
2389+
2390+
id: int = field(init=False, metadata={'sa': Column(Integer, primary_key=True)})
2391+
container_id: Optional[int] = field(default=None, metadata={'sa': Column(Integer)})
2392+
2393+
container: Optional[SimpleContainers] = field(default=None, metadata={'sa': relationship('SimpleContainers', back_populates='simple_items')})
2394+
""",
2395+
)

0 commit comments

Comments
 (0)