Skip to content

Say what required the foreign key to resolve in naming conventions - #13499

Open
hamodywe wants to merge 1 commit into
sqlalchemy:mainfrom
hamodywe:fix/naming-convention-referred-column-unresolvable-error
Open

Say what required the foreign key to resolve in naming conventions#13499
hamodywe wants to merge 1 commit into
sqlalchemy:mainfrom
hamodywe:fix/naming-convention-referred-column-unresolvable-error

Conversation

@hamodywe

Copy link
Copy Markdown
Contributor

Fixes: #5350

Description

A naming convention using %(referred_column_0_name)s reads fk.column while the constraint name is being built, which happens when the constraint is attached to its table. For a string-based ForeignKey that can be before the referenced Table exists in the MetaData — every other path resolves the target lazily, which is why the same models work when the referenced table is declared first, or when the convention uses no referred_ token.

Isolated on 2.1.0b4, with the child table declared first:

case result
no naming convention works
convention without referred_* works
convention with referred_column_0_name NoReferencedTableError

The error named the column and the missing table and said nothing about the naming convention, so there was nothing in the message to lead anyone to the cause.

This re-raises it naming the token and the three ways out: declare the referenced table first, pass the Column object rather than a string, or use %(referred_table_name)s, which is read from the string and needs no resolution. The exception type and its table_name / column_name attributes are unchanged, so existing except NoReferencedTableError handling keeps working.

Scoped to the error message per the note on the issue that the naming mechanics are not expected to be easy to change here.

Verification

  • new tests pass; revert-checked — stashing only naming.py fails test_fk_ref_unresolvable_target_reports_the_convention with the old bare message
  • test/sql/ + test/base/: 9037 passed
  • test/orm/declarative/: 2850 passed
  • black --check and flake8 (project config) clean

Supersedes #13498, which was auto-closed because its description was left as the template with an empty Fixes: line.

A naming convention using %(referred_column_0_name)s reads fk.column
while the constraint name is being built, which happens when the
constraint is attached to its table. For a string-based ForeignKey that
can be before the referenced Table exists in the MetaData -- every other
path resolves the target lazily, so the same models work when the
referenced table is declared first, or when the convention uses no
referred_ token.

The resulting NoReferencedTableError named the column and the missing
table and said nothing about the naming convention, leaving nothing in
the message to lead anyone to the cause.

Re-raise it naming the token and the three ways out: declare the
referenced table first, pass the Column object rather than a string, or
use %(referred_table_name)s, which is read from the string and needs no
resolution. The exception type and its table_name/column_name
attributes are unchanged, so existing handling keeps working.

Scoped to the error per the note on the issue that the naming mechanics
are not expected to be easy to change here.

Fixes: sqlalchemy#5350
@sqla-tester

Copy link
Copy Markdown
Collaborator

Thanks! Issue #5350 is now marked code review in progress and no longer open for pull requests, so this pull request holds the review for it and another one won't land on top of your work. If this pull request is abandoned, a maintainer can put open for pull requests back on #5350 to reopen it to others.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NoReferencedColumnError when using referred_column_0[[_]N]_name in FK naming convention

2 participants