#29367: bulk_create with manual primary_key don't update instances state
-------------------------------------+-------------------------------------
Reporter: Oscar Esgalha | Owner: Oscar
| Esgalha
Type: Bug | Status: assigned
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution:
Keywords: bulk_create, | Triage Stage:
primary_key | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Oscar Esgalha:
Old description:
> Given a model with manually defined primary keys:
> {{{
> #!python
> 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:
> {{{
> #!python
> 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:
> {{{
> #!python
> class Group(models.Model):
> ext_id = models.CharField(primary_key=True, max_length=32)
>
> class Analist(models.Model):
> ext_id = models.CharField(primary_key=True, max_length=32)
> groups = models.ManyToManyField(Group)
>
> group_aaa = Group.objects.get(ext_id='AAA')
>
> analist_eee = Analist(ext_id='EEE')
> Analist.objects.bulk_create([analist_eee])
>
> analist_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:
> {{{
> analist_eee = Analist(ext_id='EEE')
> Analist.objects.bulk_create([analist_eee])
> analist_eee._state.db = 'default'
>
> analist_eee.groups.set([group_aaa]) # And now it works
> }}}
New description:
Given a model with manually defined primary keys:
{{{
#!python
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:
{{{
#!python
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:
{{{
#!python
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
}}}
--
--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:3>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/066.9b60345056430f40bfde14e9f479ccb8%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.