fix(migrations): migration serialization bugs for PK fields#2195
fix(migrations): migration serialization bugs for PK fields#2195seladb wants to merge 2 commits into
Conversation
- Preserve `generated=False` on PK fields in deconstruct() output - Do not skip PK fields with `source_field="id"` in CreateModel migration
|
@waketzheng @abondar I'm not sure why the coverage workflow didn't start, can you cancel and restart it (I don't have permissions to do so)? |
|
@abondar @waketzheng can you please review this PR? |
|
@seladb Thanks for tracking this down. The fixes make sense for the two cases discussed in #2176: preserving One thing worth considering is whether the The current change fixes the reported PK case: if name in source_fields and not getattr(field, "pk", False):
continueBut the underlying issue seems a bit broader: a field should only be skipped when its name is the backing DB column for another field, such as the generated A slightly more general approach might be: source_fields = {
field.source_field
for name, field in operation.fields
if (
field is not None
and getattr(field, "source_field", None)
and field.source_field != name
)
}Then the existing It may also be worth adding one regression test for the non-PK version of the same pattern, for example: ("name", fields.CharField(max_length=100, source_field="name"))The Overall this looks like the right direction; the main question is whether the |
Description
Fixes 2 bugs that were discovered in #2176
Motivation and Context
Two bugs in migration serialization when a PK field is configured with
non-default attributes:
generated=Falseon PK fields was lost during serialization —Field.deconstruct()only emittedgeneratedwhen the value wastruthy. If a PK field explicitly set
generated=False, the kwarg wasomitted, causing the field to revert to its per-engine default
(
Truefor IntField) on deserialization. The fix includes thegeneratedkwarg wheneverself.pkis true, preserving the explicitvalue.
source_field="<FIELD_NAME>"were dropped from CreateModel —MigrationWriter._format_create_model()collected allsource_fieldvalues and skipped any field whose
nameappeared in that set. When aPK field had
source_field="<FIELD_NAME>", its own name matched the set entryand it was incorrectly excluded from the migration output. The fix
exempts PK fields from this deduplication logic.
How Has This Been Tested?
generatedin PK and non-PK fieldssource_fieldthat is similar to the field nameChecklist: