[Django] #29367: bulk_create with manual primary_key don't update instances state

25 views
Skip to first unread message

Django

unread,
Apr 27, 2018, 1:27:18 PM4/27/18
to django-...@googlegroups.com
#29367: bulk_create with manual primary_key don't update instances state
-------------------------------------+-------------------------------------
Reporter: Oscar | Owner: nobody
Esgalha |
Type: Bug | Status: new
Component: Database | Version: master
layer (models, ORM) | Keywords: bulk_create,
Severity: Normal | primary_key
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
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
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/29367>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Apr 27, 2018, 1:27:40 PM4/27/18
to django-...@googlegroups.com
#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
-------------------------------------+-------------------------------------
Changes (by Oscar Esgalha):

* status: new => assigned
* owner: nobody => Oscar Esgalha


--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:1>

Django

unread,
Apr 27, 2018, 1:35:47 PM4/27/18
to django-...@googlegroups.com
#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
-------------------------------------+-------------------------------------

Comment (by Oscar Esgalha):

PR with proposed fix:
https://github.com/django/django/pull/9902

--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:2>

Django

unread,
Apr 27, 2018, 1:56:39 PM4/27/18
to django-...@googlegroups.com
#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:

New description:


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

unread,
Apr 27, 2018, 5:09:25 PM4/27/18
to django-...@googlegroups.com
#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: Accepted
primary_key |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):

* has_patch: 0 => 1
* stage: Unreviewed => Accepted


--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:4>

Django

unread,
Apr 27, 2018, 6:20:10 PM4/27/18
to django-...@googlegroups.com
#29367: bulk_create with manual primary_key don't update instances state
-------------------------------------+-------------------------------------
Reporter: Oscar Esgalha | Owner: Oscar
| Esgalha
Type: Bug | Status: closed

Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: fixed

Keywords: bulk_create, | Triage Stage: Accepted
primary_key |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham <timograham@…>):

* status: assigned => closed
* resolution: => fixed


Comment:

In [changeset:"6d1f5769455ad8e1384087b92aa5839c3540d9ba" 6d1f576]:
{{{
#!CommitTicketReference repository=""
revision="6d1f5769455ad8e1384087b92aa5839c3540d9ba"
Fixed #29367 -- Fixed model state on objects with a primary key created
with QuerySet.bulk_create().
}}}

--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:5>

Django

unread,
Apr 30, 2018, 9:54:35 AM4/30/18
to django-...@googlegroups.com
#29367: bulk_create with manual primary_key don't update instances state
-------------------------------------+-------------------------------------
Reporter: Oscar Esgalha | Owner: Oscar
| Esgalha
Type: Bug | Status: closed
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: bulk_create, | Triage Stage: Accepted
primary_key |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Oscar Esgalha):

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

--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:6>

Django

unread,
May 1, 2018, 10:14:30 AM5/1/18
to django-...@googlegroups.com
#29367: bulk_create with manual primary_key don't update instances state
-------------------------------------+-------------------------------------
Reporter: Oscar Esgalha | Owner: Oscar
| Esgalha
Type: Bug | Status: closed
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: bulk_create, | Triage Stage: Accepted
primary_key |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Tim Graham):

It doesn't qualify for a backport based on our
[https://docs.djangoproject.com/en/dev/internals/release-process
/#supported-versions supported versions policy].

--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:7>

Django

unread,
May 2, 2018, 8:30:55 AM5/2/18
to django-...@googlegroups.com
#29367: bulk_create with manual primary_key don't update instances state
-------------------------------------+-------------------------------------
Reporter: Oscar Esgalha | Owner: Oscar
| Esgalha
Type: Bug | Status: closed
Component: Database layer | Version: master
(models, ORM) |
Severity: Normal | Resolution: fixed
Keywords: bulk_create, | Triage Stage: Accepted
primary_key |
Has patch: 1 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Oscar Esgalha):

I see.
Thank you for the answer.

--
Ticket URL: <https://code.djangoproject.com/ticket/29367#comment:8>

Reply all
Reply to author
Forward
0 new messages