diff options
| author | Simon Charette <charette.s@gmail.com> | 2024-12-09 18:38:18 -0500 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2025-02-01 18:43:10 +0100 |
| commit | 4608d34b346c28d5d227363c881d3279378f40b3 (patch) | |
| tree | b769a1916458f322d5f8de7d1358d54e2a913d3d /tests/bulk_create | |
| parent | 0d131c158234df544532830b7752fe43fcf4bb39 (diff) | |
Fixed #36088 -- Avoided unnecessary DEFAULT usage on bulk_create().
When all values of a field with a db_default are DatabaseDefault, which
is the case most of the time, there is no point in specifying explicit
DEFAULT for all INSERT VALUES as that's what the database will do anyway
if not specified.
In the case of PostgreSQL doing so can even be harmful as it prevents
the usage of the UNNEST strategy and in the case of Oracle, which
doesn't support the usage of the DEFAULT keyword, it unnecessarily
requires providing literal db defaults.
Thanks Lily Foote for the review.
Diffstat (limited to 'tests/bulk_create')
| -rw-r--r-- | tests/bulk_create/models.py | 6 | ||||
| -rw-r--r-- | tests/bulk_create/tests.py | 26 |
2 files changed, 32 insertions, 0 deletions
diff --git a/tests/bulk_create/models.py b/tests/bulk_create/models.py index 8a21c7dfa1..f0df9da66e 100644 --- a/tests/bulk_create/models.py +++ b/tests/bulk_create/models.py @@ -3,6 +3,7 @@ import uuid from decimal import Decimal from django.db import models +from django.db.models.functions import Now from django.utils import timezone try: @@ -141,3 +142,8 @@ class RelatedModel(models.Model): name = models.CharField(max_length=15, null=True) country = models.OneToOneField(Country, models.CASCADE, primary_key=True) big_auto_fields = models.ManyToManyField(BigAutoFieldModel) + + +class DbDefaultModel(models.Model): + name = models.CharField(max_length=10) + created_at = models.DateTimeField(db_default=Now()) diff --git a/tests/bulk_create/tests.py b/tests/bulk_create/tests.py index 7b86a2def5..83ff8e4514 100644 --- a/tests/bulk_create/tests.py +++ b/tests/bulk_create/tests.py @@ -17,10 +17,12 @@ from django.test import ( skipIfDBFeature, skipUnlessDBFeature, ) +from django.utils import timezone from .models import ( BigAutoFieldModel, Country, + DbDefaultModel, FieldsWithDbColumns, NoFields, NullableFields, @@ -840,3 +842,27 @@ class BulkCreateTests(TestCase): {"rank": 2, "name": "d"}, ], ) + + def test_db_default_field_excluded(self): + # created_at is excluded when no db_default override is provided. + with self.assertNumQueries(1) as ctx: + DbDefaultModel.objects.bulk_create( + [DbDefaultModel(name="foo"), DbDefaultModel(name="bar")] + ) + created_at_quoted_name = connection.ops.quote_name("created_at") + self.assertEqual( + ctx[0]["sql"].count(created_at_quoted_name), + 1 if connection.features.can_return_rows_from_bulk_insert else 0, + ) + # created_at is included when a db_default override is provided. + with self.assertNumQueries(1) as ctx: + DbDefaultModel.objects.bulk_create( + [ + DbDefaultModel(name="foo", created_at=timezone.now()), + DbDefaultModel(name="bar"), + ] + ) + self.assertEqual( + ctx[0]["sql"].count(created_at_quoted_name), + 2 if connection.features.can_return_rows_from_bulk_insert else 1, + ) |
