Changes between Version 3 and Version 4 of Ticket #29721, comment 12


Ignore:
Timestamp:
Oct 7, 2026, 2:18:00 AM (7 hours ago)
Author:
Gavin Wahl(vendor)

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #29721, comment 12

    v3 v4  
    33I believe the most realistic and reliable reproducible reproducer is to simulate a hard crash during migration recording by adding `import os; os.kill(os.getpid(), 9)` or `import sys; sys.exit()` to the first line of BaseDatabaseSchemaEditor.record_migration. A unrecoverable hard crash can happen at any time, that's why we have transactions.
    44
    5 I've reproduced the issue with a deferred_sql migration and tested this fix
     5I've reproduced the issue on postgres with atomic=True migration that uses deferred_sql, and tested this fix
    66Before: table created but migration not recorded. Migration "half applied" in inconsistent state.
    7 After: The whole transaction rolled back, tables not created and migration not recorded. Migration correct "not applied", consistent state.
    8 deferred sql correctly runs before record_migration, as in the fix for #32374, but now also in the transaction.
     7After: The whole transaction rolled back, tables not created and migration not recorded, consistent state
    98
     9Deferred sql correctly runs before record_migration, as in the fix for #32374, but now also in the transaction.
     10
     11The issue is clear from the [abbreviated] postgres logs. The django_migrations insert happens after the COMMIT of the main migration, so the migration isn't really atomic.
     12
     13Before:
     14{{{
     15BEGIN
     16CREATE TABLE "foo_foo" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "a_id" bigint NOT NULL)
     17ALTER TABLE "foo_foo" ADD CONSTRAINT "foo_foo_a_id_f8ce5994_fk_foo_foo_id" FOREIGN KEY ("a_id") REFERENCES "foo_foo" ("id") DEFERRABLE INITIALLY DEFERRED
     18CREATE INDEX "foo_foo_a_id_f8ce5994" ON "foo_foo" ("a_id")
     19COMMIT
     20INSERT INTO "django_migrations" ("app", "name", "applied") VALUES ('foo', '0001_initial', '2026-10-07 07:10:08.085619+00:00'::timestamptz) RETURNING "django_migrations"."id"
     21}}}
     22
     23After patch:
     24{{{
     25BEGIN
     26CREATE TABLE "foo_foo" ("id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, "a_id" bigint NOT NULL)
     27ALTER TABLE "foo_foo" ADD CONSTRAINT "foo_foo_a_id_f8ce5994_fk_foo_foo_id" FOREIGN KEY ("a_id") REFERENCES "foo_foo" ("id") DEFERRABLE INITIALLY DEFERRED
     28CREATE INDEX "foo_foo_a_id_f8ce5994" ON "foo_foo" ("a_id")
     29INSERT INTO "django_migrations" ("app", "name", "applied") VALUES ('foo', '0001_initial', '2026-10-07 07:13:01.602656+00:00'::timestamptz) RETURNING "django_migrations"."id"
     30COMMIT
     31}}}
     32
     33The django_migrations insert happens both after the deferred sql and inside the transaction, so it is atomic.
    1034
    1135{{{#!diff
Back to Top