#29367 closed Bug (fixed)
bulk_create with manual primary_key don't update instances state
Reported by: | Oscar Esgalha | Owned by: | Oscar Esgalha |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | bulk_create, primary_key |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Given a model with manually defined primary keys:
class State(models.Model): two_letter_code = models.CharField(max_length=2, primary_key=True)
Performing a bulk_create with model instances will not correctly update their state.
Looping through the instances and calling save() individually will result in instances with different state from instances persisted with bulk_create:
state_ca = State(two_letter_code='CA') State.objects.bulk_create([state_ca]) state_ca._state.adding # => True state_ca._state.db # => None state_ny = State(two_letter_code='NY') state_ny.save() state_ny._state.adding # => False state_ny._state.db # => 'default'
One implication of this behavior is that the instances saved with bulk_create can't be used to build relationships with model instances loaded with other Queryset API methods.
Here is a demonstration:
class Group(models.Model): ext_id = models.CharField(primary_key=True, max_length=32) class Analyst(models.Model): ext_id = models.CharField(primary_key=True, max_length=32) groups = models.ManyToManyField(Group) group_aaa = Group.objects.get(ext_id='AAA') analyst_eee = Analyst(ext_id='EEE') Analyst.objects.bulk_create([analyst_eee]) analyst_eee.groups.set([group_aaa]) # ValueError: Cannot add "<Group: AAA>": instance is on database "None", value is on database "default"
It fails when the ._state.db
is compared.
A current workaround option is to manually set the ._state.db
after the bulk_create:
analyst_eee = Analyst(ext_id='EEE') Analyst.objects.bulk_create([analyst_eee]) analyst_eee._state.db = 'default' analyst_eee.groups.set([group_aaa]) # And now it works
Change History (8)
comment:1 by , 7 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 7 years ago
comment:3 by , 7 years ago
Description: | modified (diff) |
---|
comment:4 by , 7 years ago
Has patch: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:6 by , 7 years ago
Hi,
I'm glad the patch was accepted.
But I'd like to known if this can be backported to 1.11.x? Is there anything I can do to help that?
Best regards
comment:7 by , 7 years ago
It doesn't qualify for a backport based on our supported versions policy.
PR with proposed fix:
https://github.com/django/django/pull/9902