Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to opt out from special naming when fieldname ends with _id #355

Open
1 task done
Henkhogan opened this issue Jan 3, 2025 · 2 comments
Open
1 task done

Comments

@Henkhogan
Copy link

Henkhogan commented Jan 3, 2025

Things to check first

  • I have searched the existing issues and didn't find my feature already requested there

Feature description

The code part that will handle FKs on field names that end with _id is simply driving me nuts because it can lead to inconsitent naming on parent and child tables.

if len(column_names) == 1 and column_names[0].endswith("_id"):

Please add a n option to opt-out from it

Use case

I have all my tables prefix with t_ in my db so that they are renamed like

t_child -> TChild
t_parent -> TParent

if I now have a field parent_id on the child table, I will end up with

"parent" as FK on the child table
and
"t_child" as FK on the parent table

which is inconsitent IMO

@agronholm
Copy link
Owner

OK, can you show me the schema and the code generated from it? I'd like to understand the problem better.

@Henkhogan
Copy link
Author

Henkhogan commented Mar 4, 2025

@agronholm it should be obvious when you compare the outcome of the testcases test_named_foreign_key_constraints and test_named_foreign_key_constraints_with_noidsuffix (added with the PR #356)

NORMAL

from typing import List, Optional
from sqlalchemy import ForeignKeyConstraint, Integer
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
class Base(DeclarativeBase):
    pass
class SimpleContainers(Base):
    __tablename__ = 'simple_containers'
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    simple_items: Mapped[List['SimpleItems']] = relationship('SimpleItems', \
back_populates='container')
class SimpleItems(Base):
    __tablename__ = 'simple_items'
    __table_args__ = (
        ForeignKeyConstraint(['container_id'], ['simple_containers.id'], \
name='foreignkeytest'),
    )
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    container_id: Mapped[Optional[int]] = mapped_column(Integer)
    container: Mapped['SimpleContainers'] = relationship('SimpleContainers', \
back_populates='simple_items')

WITH --noidsuffix

from typing import List, Optional
from sqlalchemy import ForeignKeyConstraint, Integer
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship
class Base(DeclarativeBase):
    pass
class SimpleContainers(Base):
    __tablename__ = 'simple_containers'
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    simple_items: Mapped[List['SimpleItems']] = relationship('SimpleItems', \
back_populates='simple_containers')
class SimpleItems(Base):
    __tablename__ = 'simple_items'
    __table_args__ = (
        ForeignKeyConstraint(['container_id'], ['simple_containers.id'], \
name='foreignkeytest'),
    )
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    container_id: Mapped[Optional[int]] = mapped_column(Integer)
    simple_containers: Mapped['SimpleContainers'] = relationship('SimpleContainers', \
back_populates='simple_items')

the FK on field container_id is usually named container (the code strips _id) but I want it to be named like the source table simple_containers

The fact that I prefix my tables with "t_" is mostly irrelevant for my request. With that convention in place, I can simply expect all FKs to start with "t_" as class members, which has some ergonomical benefits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants