sqlalchemy / sqlalchemy/alembic
add option to re-apply naming conventions for table renamed in batch mode
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 4.4k
- Forks
- 375
- PR merge metrics
- No merged PRs in 30d
Description
We thought this was a bug which we can see in discussion at #1833. however, from the point of view of "batch migrations" as a workaround for the lack of ALTER, it's not a bug.
- Batch migrations recreate a table with a new name, then drop the old table and rename the new table to the old one
- it normally uses reflection to get the full structure of the existing table, including all of its constraints (and their names). that is, the constraints that are already created in the database.
- a SQLite bug that was fixed in SQLAlchemy 2.0.45 https://github.com/sqlalchemy/sqlalchemy/issues/12924 had the behavior such that SQLite constraints where the constraint name used MixedCase would not reflect the constraint name; we'd get None for the constraint name in that case
- when batch reflection / table recreation gets None for a constraint name, it uses the configured naming convention (if any) to give the new constraint a name
- user @mbergen had a schema in SQLite using a naming convention where constraints had MixedCase.
- up through SQLAlchemy 2.0.44, @mbergen relied upon the behavior that a batch migration for SQLite where the table name changed would also rename their constraints for that new table name, so a constraint called "Old_Table_ck_1" would nicely become "New_Table_ck_1" (noting MixedCase names)
- the bug fixed in 2.0.45 meant the operation would now successfully reflect the constraint's name of "Old_Table_ck_1" and leave it unchanged when creating a new table.
- the behavior for constraint names with lowercase on SQLite as well as PG, MySQL was always that the constraint name was reflected, and applying a table rename and/or a batch recreate didnt change those names.
- this behavior also matches what happens if we use ALTER TABLE. If you have a table named "Old_Table" and your naming convention made a constraint "Old_Table_ck_1", and you do "ALTER TABLE 'Old_Table' RENAME TO 'New_Table'", that's not going to rename your "Old_Table_ck1" constraint - that old name stays.
- this all means the current behavior plus the 2.0.45 sqlite fix for alembic is "correct", for a "correct" of "batch migrations are a substitute for ALTER TABLE".
So. With all of the above establishing this was not a bug, the batch mode thing does give us a way to...rename a table and drop and recreate all its constraints! so maybe it would be nice for there to be an option, "rename_constraints_with_convention=" or something like that, so that you can actually have that behavior @mbergen had come to rely upon.
that's the issue here. feature request
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading discussion #1833 and the batch migration behavior described here, focusing on reflection, table recreation, and configured naming conventions. Define how an opt-in convention should rename recreated constraints while preserving the current default behavior, then verify the option for renamed tables and existing reflected constraint names across the relevant database cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python, sqlalchemy, sqlite
- Domain
- databases
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100