Opened 4 years ago

Last modified 4 years ago

#23610 new Cleanup/optimization

Removing a null constraint can lead to race conditions with migrations

Reported by: Josh Smeaton Owned by: nobody
Component: Documentation Version: 1.7
Severity: Normal Keywords: migrations
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I think a race condition exists when removing a null constraint that doesn't contain a default. This discussion started with regards to #23609. The flow here was changing a column from having a null to having a default:

IntegerField(null=True) -> IntegerField(default=42)

And the race condition:

  • Deploy migration
  • Update App Server 1 code
  • App Server 2 tries to write to the table, and gets a write error (since it doesn't yet have the default in its models file)
  • Update App Server 2 code

For a write heavy table, this could result in many failed writes.

I think we should be clear, and document, that removing a null on a column should always be done in two steps:

  1. Add a default to the column. Deploy migration. Deploy app code.
  2. Remove the null and the default from the column. Deploy migration. Deploy app code.

Perhaps there could be a check that ensures that removing a null always requires an existing default to exist.

Change History (1)

comment:1 Changed 4 years ago by Loic Bistuer

Component: MigrationsDocumentation
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization

There are many cases where old app code won't work after a migration applied (e.g. adding a new column with NOT NULL, removing a column, etc.). I reckon we should just document that people are expected to run the new app code right after applying a migration.

There are certainly ways around it, but it's important people understand that nothing special is done at the framework level.

Note: See TracTickets for help on using tickets.
Back to Top