Opened 3 weeks ago

Closed 3 weeks ago

Last modified 3 weeks ago

#37234 closed Bug (fixed)

bulk_create fails when related objects got PKs later

Reported by: Filip Sedlák Owned by: Akshat Sparsh
Component: Database layer (models, ORM) Version: 6.0
Severity: Release blocker Keywords:
Cc: Filip Sedlák, Simon Charette Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

This is a regression betwen Django 5.2 and 6.0.

Here's a short reproducer test that, when added to tests/bulk_create/tests.py fails with an AssertionError within bulk_create.

    @skipUnlessDBFeature("can_return_rows_from_bulk_insert")
    def test_pk_from_related_instance_saved_after_init(self):
        country = Country(name="Syldavia", iso_two_letter="SW")
        related = RelatedModel(country=country)
        country.save()
        RelatedModel.objects.bulk_create([related])
        self.assertEqual(related.country_id, country.pk)

Failure:

  File "/Users/krab/workspace/django/tests/bulk_create/tests.py", line 901, in test_pk_from_related_instance_saved_after_init
    RelatedModel.objects.bulk_create([related])
    ^^^^^^^^^^^^^^^
  File "/Users/krab/workspace/django/django/db/models/manager.py", line 87, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
    ^^^^^^^
  File "/Users/krab/workspace/django/django/db/models/query.py", line 913, in bulk_create
    assert len(returned_columns) == len(objs_without_pk)
    ^^^

It looks like Django used to support this case intentionally, calling ._prepare_related_fields_for_save(operation_name="bulk_create") within bulk_create but a recent change breaks that.

I've never contributed to Django, but I'm willing to work on a fix if you're interested.

Change History (15)

comment:1 by Sarah Boyce, 3 weeks ago

Cc: Simon Charette added
Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

Thank you for the test and ticket!
Regression in 7d9aab8da0a06787d649762a702e1a518d843a63 (refs #36260)

Marking as a release blocker as this was introduced in the latest feature release. If you think you have a fix, you're very welcome to raise a PR! You can review/test a PR from a different contributor. We will try to fix this before the planned release next week (Tuesday 4th August)

Version 0, edited 3 weeks ago by Sarah Boyce (next)

comment:2 by Akshat Sparsh, 3 weeks ago

Owner: set to Akshat Sparsh
Status: newassigned

comment:3 by Akshat Sparsh, 3 weeks ago

Has patch: set

PR

The full test suite passes on SQLite. The bulk_create tests also pass on PostgreSQL 18 and MariaDB 11.8.

comment:4 by Jacob Walls, 3 weeks ago

Triage Stage: AcceptedReady for checkin

comment:5 by Jacob Walls, 3 weeks ago

Has patch: unset
Needs tests: set
Patch needs improvement: set
Triage Stage: Ready for checkinAccepted

Left notes on an additional test case we might want.

comment:6 by Akshat Sparsh, 3 weeks ago

Has patch: set
Needs tests: unset
Patch needs improvement: unset

comment:7 by Jacob Walls, 3 weeks ago

Patch needs improvement: set

comment:8 by Akshat Sparsh, 3 weeks ago

Patch needs improvement: unset

comment:9 by Jacob Walls, 3 weeks ago

Triage Stage: AcceptedReady for checkin

comment:10 by Jacob Walls, 3 weeks ago

Patch needs improvement: set
Triage Stage: Ready for checkinAccepted

comment:11 by Akshat Sparsh, 3 weeks ago

Patch needs improvement: unset

comment:12 by Jacob Walls, 3 weeks ago

Triage Stage: AcceptedReady for checkin

I restored the patch to the state suggested by Filip and agreed with Simon. (The detour I took into expression assignment is something we can more leisurely evaluate without backporting in #37239.)

comment:13 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

Resolution: fixed
Status: assignedclosed

In c9ff757:

Fixed #37234 -- Fixed bulk_create() for late-saved related primary keys.

Objects with a primary key supplied by a late-saved related instance
were partitioned before their related fields were prepared. This
caused an assertion failure on backends returning rows from bulk
inserts.

Regression in 7d9aab8da0a06787d649762a702e1a518d843a63.

comment:14 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

In c800c8a:

[6.1.x] Fixed #37234 -- Fixed bulk_create() for late-saved related primary keys.

Objects with a primary key supplied by a late-saved related instance
were partitioned before their related fields were prepared. This
caused an assertion failure on backends returning rows from bulk
inserts.

Regression in 7d9aab8da0a06787d649762a702e1a518d843a63.

Backport of c9ff757a55392b1f50968eb89fe775f6155168d8 from main.

comment:15 by Jacob Walls <jacobtylerwalls@…>, 3 weeks ago

In c81c6a9:

[6.0.x] Fixed #37234 -- Fixed bulk_create() for late-saved related primary keys.

Objects with a primary key supplied by a late-saved related instance
were partitioned before their related fields were prepared. This
caused an assertion failure on backends returning rows from bulk
inserts.

Regression in 7d9aab8da0a06787d649762a702e1a518d843a63.

Backport of c9ff757a55392b1f50968eb89fe775f6155168d8 from main.

Note: See TracTickets for help on using tickets.
Back to Top