Skip to content

Honor db_constraint=False in migration schema editor - #2226

Open
youdie006 wants to merge 2 commits into
tortoise:developfrom
youdie006:fix/migration-db-constraint
Open

youdie006 wants to merge 2 commits into
tortoise:developfrom
youdie006:fix/migration-db-constraint

Conversation

@youdie006

Copy link
Copy Markdown

Description

The migration schema editor always emitted the FOREIGN KEY reference for ForeignKeyField / ManyToManyField, ignoring db_constraint=False — unlike the runtime schema generator, which respects it. grep db_constraint tortoise/migrations/ returned zero matches, confirming the migration subsystem ignored the flag.

Motivation and Context

Closes #2223. Models that set db_constraint=False (to avoid a hard DB-level FK while keeping the ORM relation) still got a constrained FK in generated migrations, defeating the flag.

How Has This Been Tested?

  • _get_fk_field_definition: guard the _get_fk_reference_string(...) append on fk_field.db_constraint (mirrors backends/base/schema_generator.py:264). Covers create_model and add_field.
  • _get_m2m_table_definition: a no-constraint through-table template selected when not field.db_constraint (mirrors schema_generator.py:328/370); the unique index is still emitted.
  • 3 new tests in tests/migrations/test_schema_editor_sql.py (FK in create_model, FK via add_field, M2M) assert no REFERENCES/FOREIGN KEY while the column remains — red→green. Full sqlite suite: 1912 passed, 0 failures.

Checklist

  • Tests added
  • CHANGELOG.rst updated
  • ruff check / ruff format --check clean

@codspeed

codspeed Bot commented Jun 24, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 24 untouched benchmarks


Comparing youdie006:fix/migration-db-constraint (53d9596) with develop (bc4f971)

Open in CodSpeed

' ("{forward_field}") ON DELETE CASCADE\n'
"){extra}{comment};"
)
M2M_TABLE_NO_CONSTRAINT_TEMPLATE = (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does this template work with MySQL?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

No, it didn't. Sorry for the slow answer. MySQL, MSSQL and Oracle build the through table from their own M2M_TABLE_TEMPLATE, so the base template never reached them and they still emitted both foreign keys. The FK column path was fine, since all of them go through the base _get_fk_field_definition.

5cdedc6 adds a no-constraint template to each of the three. I also added a db_constraint=False scenario to test_schema_editor_backend_parity.py, which compares every editor's SQL with the runtime schema generator: on develop it fails for all five backends, with only the first commit it fails for MySQL, MSSQL and Oracle, and now it passes for all. Rebased onto develop as well.

@youdie006
youdie006 force-pushed the fix/migration-db-constraint branch from 53d9596 to 5cdedc6 Compare October 19, 2026 00:23
The migration schema editor always emitted the FOREIGN KEY reference for
ForeignKeyField/ManyToManyField regardless of db_constraint, unlike the runtime
schema generator. Guard FK emission in _get_fk_field_definition on
fk_field.db_constraint, and add a no-constraint M2M through-table template,
mirroring schema_generator. The plain column (and through table) are still
emitted; only the FK constraint is dropped when db_constraint=False.
These editors build the through table from their own template, so the base
change did not reach them. Add a db_constraint=False scenario to the
backend parity test, which compares each editor with the runtime schema
generator.
@youdie006
youdie006 force-pushed the fix/migration-db-constraint branch from 5cdedc6 to faebf04 Compare October 19, 2026 23:41

This branch has not been deployed

No deployments
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.

Regarding db_constraint, I think this is a bug

2 participants