#37031: Improve writing migrations guide to adding unique fields on existing table
-------------------------------------+-------------------------------------
Reporter: Clifford Gama | Owner: Clifford
Type: | Gama
Cleanup/optimization | Status: assigned
Component: Documentation | Version: dev
Severity: Normal | Resolution:
Keywords: migrations | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Comment (by Simon Charette):
> All three operations can be placed in a single migration, which is
simpler to follow and has the added benefit of being atomic — removing the
race condition that is currently warned about in the docs.
Some warnings about this approach
1. This will hold a lock on the table for the whole duration of the
transaction which is not practical in many cases. That's the reason why
[
https://docs.djangoproject.com/en/6.0/howto/writing-migrations/#non-
atomic-migrations we document that data migration should not be run in a
transaction].
2. This won't change anything on MySQL which doesn't support transactional
DDL.
I still believe the approach proposed by Shai in #23932:comment:2 is
correct.
If you
1. Add the field as `(null=True, unique=True, default=uuid.uuid4)` and run
the migration
2. Deploy the changes so any row created from that point sets a value
3. Run a migration that performs a backfill in a non-atomic matter
4. Run a migration that drops `null=True`
There are no race conditions possible.
--
Ticket URL: <
https://code.djangoproject.com/ticket/37031#comment:5>