Add cookbook recipe for adding a non-nullable column - #1838
Open
ArockiaRajamanickam wants to merge 1 commit into
Open
Add cookbook recipe for adding a non-nullable column#1838ArockiaRajamanickam wants to merge 1 commit into
ArockiaRajamanickam wants to merge 1 commit into
Conversation
Documents the add-nullable, backfill, then set NOT NULL pattern agreed on in issue sqlalchemy#681, along with the server_default alternative and a warning about table locking on a running application.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the cookbook recipe requested in the second bullet of #681: how to add a non-nullable column to a table that already has rows, without a server default.
The recipe follows what was agreed in the thread rather than inventing an approach:
UPDATE, thenalter_column(nullable=False)), which was the one both of you settled on... warning::covers zzzeek's two points: theUPDATE/ALTERcan lock the table and take a live site down on a large dataset, and adding a non-nullable column is hard to make work against an application that keeps running during the migration.server_defaultalternative is mentioned second, with the note that dropping a server default behaves differently across backends.:ref:batch_migrations`` instead.The backfill uses the lightweight
sa.table()/sa.column()constructs rather than the application model, so the migration keeps working as the model changes.Scope: this PR only covers the cookbook half of #681. The
env.pylogging half was declined by zzzeek in the same thread, so it is left alone, and I have not usedFixes:since the issue bundles both requests.Verification:
MigrationContextagainst SQLite 3.53 and PostgreSQL 16: confirmed the naive one-stepadd_column(nullable=False)fails on a populated table, that the three-step recipe leaves an enforcedNOT NULLcolumn, that a subsequentNULLinsert is rejected, that the downgrade drops the column, and that theserver_defaultvariant leaves no residual default.sphinx -b htmlbuilds with no new warnings; the:ref:and:meth:targets and the two SQLAlchemy intersphinx links all resolve.One note on the SQLite cross-reference: the
seealsosays thenullable=Falsestep may need batch mode on backends with limitedALTERsupport, rather than stating flatly that SQLite cannot do it. While testing, SQLite 3.53 acceptedALTER TABLE ... ALTER COLUMN ... SET NOT NULLdirectly, so the absolute phrasing would not have been accurate on current versions. Happy to reword if you would rather it match the framing inbatch.rst.I used an AI assistant while drafting this; the wording and the testing above are mine and I have checked the content against the thread and the docs build.