Ticket #36550: ticket_36550_bulk_create_composite_auto_now_add.patch

File ticket_36550_bulk_create_composite_auto_now_add.patch, 5.9 KB (added by Jason Hall, 4 weeks ago)
  • django/db/models/query.py

    diff --git a/django/db/models/query.py b/django/db/models/query.py
    index 9f245b02ca..48c73c78e6 100644
    a b class QuerySet(AltersData):  
    674674    acreate.alters_data = True
    675675
    676676    def _prepare_for_bulk_create(self, objs):
     677        opts = self.model._meta
    677678        objs_with_pk, objs_without_pk = [], []
     679        pk = opts.pk
     680        pk_fields = list(getattr(pk, "fields", (pk,)))
     681
     682        def _pk_is_complete(obj):
     683            for f in pk_fields:
     684                v = getattr(obj, f.attname)
     685                if v is None or isinstance(v, DatabaseDefault):
     686                    return False
     687            return True
     688
    678689        for obj in objs:
    679690            if isinstance(obj.pk, DatabaseDefault):
    680691                objs_without_pk.append(obj)
    681             elif obj._is_pk_set():
     692            elif _pk_is_complete(obj):
    682693                objs_with_pk.append(obj)
    683694            else:
    684                 obj.pk = obj._meta.pk.get_pk_value_on_save(obj)
    685                 if obj._is_pk_set():
     695                obj.pk = opts.pk.get_pk_value_on_save(obj)
     696                if _pk_is_complete(obj):
    686697                    objs_with_pk.append(obj)
    687698                else:
    688699                    objs_without_pk.append(obj)
    class QuerySet(AltersData):  
    839850                if (
    840851                    connection.features.can_return_rows_from_bulk_insert
    841852                    and on_conflict is None
     853                    and opts.db_returning_fields
     854                    and objs_without_pk
    842855                ):
    843856                    assert len(returned_columns) == len(objs_without_pk)
    844857                for obj_without_pk, results in zip(objs_without_pk, returned_columns):
  • tests/composite_pk/test_create.py

    diff --git a/tests/composite_pk/test_create.py b/tests/composite_pk/test_create.py
    index 38ad9690fb..7ace973d8f 100644
    a b  
    11from django.db import IntegrityError
    22from django.test import TestCase, skipUnlessDBFeature
    33
    4 from .models import Post, Tenant, User
     4from .models import Post, Tenant, User, TimeStamped
    55
    66
    77class CompositePKCreateTests(TestCase):
    class CompositePKCreateTests(TestCase):  
    7878        self.assertEqual(obj_3.pk, (obj_3.tenant_id, obj_3.id))
    7979        self.assertEqual(obj_3.email, "user8214@example.com")
    8080
     81    def test_bulk_create_auto_now_add_primary_key(self):
     82        objs = [TimeStamped(id=1), TimeStamped(id=2), TimeStamped(id=3)]
     83        created = TimeStamped.objects.bulk_create(objs)
     84        self.assertEqual(len(created), 3)
     85        self.assertEqual(TimeStamped.objects.count(), 3)
     86        for db_obj in TimeStamped.objects.all():
     87            self.assertIsNotNone(db_obj.pk)
     88        for obj in created:
     89            self.assertIsNotNone(obj.pk)
     90
    8191    @skipUnlessDBFeature(
    8292        "supports_update_conflicts",
    8393        "supports_update_conflicts_with_target",
Back to Top