Visitar URL original
UniqueConstraint and Index withheld from table via attach_to_table flag, and appended to table via append_constraint by bekapono · Pull Request #13399 · sqlalchemy/sqlalchemy · GitHub
Skip to content

UniqueConstraint and Index withheld from table via attach_to_table flag, and appended to table via append_constraint - #13399

Open
bekapono wants to merge 7 commits into
sqlalchemy:mainfrom
bekapono:flag_attach_to_table
Open

bekapono wants to merge 7 commits into
sqlalchemy:mainfrom
bekapono:flag_attach_to_table

Conversation

@bekapono

@bekapono bekapono commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Description

attach_to_table has been included for UniqueConstraint and Index to allow users to choose whether to include or withhold them from the Table (Table.constraints for UniqueConstraint, Table.indexes for Index). attach_to_table defaults to True for both UniqueConstraint and Index. So if set to True or not included UniqueConstraint / Index will be added to the Table.

For UniqueConstraint, setting attach_to_table to False prevents parent.constraints.add(self) from executing in Column._set_parent(). attach_to_table is checked via getattr
For Index, setting attach_to_table to False prevents table.indexes.add(self) from executing in Index._set_parent()

force_attach has been included in Table.append_constraints(), and carried via **kw , to allow users to override attach_to_table. For situations where UniqueConstraint or Index was defined before the Table creation and attach_to_table is set to False, users can use that same UniqueConstraint or Index to append to table at a later time. For example unique_constraint = UniqueConstraint("x", attach_to_table=False) or index = Index("x", attach_to_table=False), then Table is defined, then Table.append_constraint(unique_constraint) or Table.append_constraint(index).

For UniqueConstraint, regardless of attach_to_table, using Table.append_constraint(constriant) allows for execution of parent.constraints.add(self) in Column._set_parent().
For Index, regardless of attach_to_table, using Table.append_constraint(index) allows for execution of table.indexes.add(self) in Index._set_parent().

Fixes: #13048

Checklist

This pull request is:

  • A documentation / typographical / small typing error fix
    • Good to go, no issue or tests are needed
  • A short code fix
    • please include the issue number, and create an issue if none exists, which
      must include a complete example of the issue. one line code fixes without an
      issue and demonstration will not be accepted.
    • Please include: Fixes: #<issue number> in the commit message
    • please include tests. one line code fixes without tests will not be accepted.
  • A new feature implementation
    • please include the issue number, and create an issue if none exists, which must
      include a complete example of how the feature would look.
    • Please include: Fixes: #<issue number> in the commit message
    • please include tests.

Have a nice day!

@bekapono

Copy link
Copy Markdown
Contributor Author

Some concerns i have:

  1. There are test cases where I do 3 asserts, attach_to_table is True then False and then not include attach_to_table, was wondering if I should have broken up the test case so it's only one assert per, or is the current version okay?
  2. I'm hesitant on how i left UniqueConstraint's initializer.

@zzzeek

zzzeek commented Jun 30, 2026

Copy link
Copy Markdown
Member

for those tests, we try to get the best of both worlds, that is, just one test method, but still keeping things separate, using either @testing.combinations or @testing.variation. both of these are facades on top of pytest.mark.parametrize and if you're using an LLM it knows how to figure this out. so in these cases you might use a @testing.variation for "attach_to_table", [None, True, False].

as far as the initializer, overall this feature still has me a bit nervous any suggestions @CaselIT ?

@bekapono

bekapono commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Thank you, I made changes to the test methods to include testing.variation.
I'll wait to see if CaseIT has any suggestions then i'll commit the changes.

My reasoning for implementing UniqueConstraint initializer was I wanted to make sure that attach_to_table was only available for UniqueConstraint. Now the actual syntax/implementation of the initializer I was hesitant so I just looked at other classes that inherited ColumnCollectionConstraint to see how they were implemented, I ended up following PrimaryKeyConstraint initializer.

Comment thread lib/sqlalchemy/sql/schema.py Outdated
deferrable: Optional[bool] = None,
initially: Optional[str] = None,
info: Optional[_InfoType] = None,
attach_to_table: bool = True,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attach_to_table=False is still ignored for CheckConstraint, ForeignKeyConstraint, and PrimaryKeyConstraint: it gets swallowed by **dialect_kw with an SAWarning and each constraint is still attached. #13048 explicitly asks for all constraints, but this only exposes the flag on UniqueConstraint.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the correction! I'll make the changes to allow all constraints to utilize the attach_to_table flag instead of just UniqueConstraint

@bekapono
bekapono force-pushed the flag_attach_to_table branch from f01ac20 to a4375aa Compare September 24, 2026 18:52
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.

Add option for disabling automatic addition of constraint/indexes to the table

3 participants