|
1 | 1 | import decimal |
2 | 2 |
|
3 | 3 | from django.core.management.color import no_style |
4 | | -from django.db import NotSupportedError, connection, transaction |
| 4 | +from django.db import NotSupportedError, connection, models, transaction |
5 | 5 | from django.db.backends.base.operations import BaseDatabaseOperations |
6 | 6 | from django.db.models import DurationField |
7 | 7 | from django.db.models.expressions import Col |
|
11 | 11 | TransactionTestCase, |
12 | 12 | override_settings, |
13 | 13 | skipIfDBFeature, |
| 14 | + skipUnlessDBFeature, |
14 | 15 | ) |
15 | 16 | from django.utils import timezone |
16 | 17 |
|
17 | | -from ..models import Author, Book |
| 18 | +from ..models import Author, Book, Person |
18 | 19 |
|
19 | 20 |
|
20 | 21 | class SimpleDatabaseOperationTests(SimpleTestCase): |
@@ -201,6 +202,55 @@ def test_subtract_temporals(self): |
201 | 202 | with self.assertRaisesMessage(NotSupportedError, msg): |
202 | 203 | self.ops.subtract_temporals(duration_field_internal_type, None, None) |
203 | 204 |
|
| 205 | + @skipUnlessDBFeature("max_query_params") |
| 206 | + def test_bulk_batch_size_limited(self): |
| 207 | + max_query_params = connection.features.max_query_params |
| 208 | + objects = range(max_query_params + 1) |
| 209 | + first_name_field = Person._meta.get_field("first_name") |
| 210 | + last_name_field = Person._meta.get_field("last_name") |
| 211 | + composite_pk = models.CompositePrimaryKey("first_name", "last_name") |
| 212 | + composite_pk.fields = [first_name_field, last_name_field] |
| 213 | + |
| 214 | + self.assertEqual(connection.ops.bulk_batch_size([], objects), len(objects)) |
| 215 | + self.assertEqual( |
| 216 | + connection.ops.bulk_batch_size([first_name_field], objects), |
| 217 | + max_query_params, |
| 218 | + ) |
| 219 | + self.assertEqual( |
| 220 | + connection.ops.bulk_batch_size( |
| 221 | + [first_name_field, last_name_field], objects |
| 222 | + ), |
| 223 | + max_query_params // 2, |
| 224 | + ) |
| 225 | + self.assertEqual( |
| 226 | + connection.ops.bulk_batch_size([composite_pk, first_name_field], objects), |
| 227 | + max_query_params // 3, |
| 228 | + ) |
| 229 | + |
| 230 | + @skipIfDBFeature("max_query_params") |
| 231 | + def test_bulk_batch_size_unlimited(self): |
| 232 | + objects = range(2**16 + 1) |
| 233 | + first_name_field = Person._meta.get_field("first_name") |
| 234 | + last_name_field = Person._meta.get_field("last_name") |
| 235 | + composite_pk = models.CompositePrimaryKey("first_name", "last_name") |
| 236 | + composite_pk.fields = [first_name_field, last_name_field] |
| 237 | + |
| 238 | + self.assertEqual(connection.ops.bulk_batch_size([], objects), len(objects)) |
| 239 | + self.assertEqual( |
| 240 | + connection.ops.bulk_batch_size([first_name_field], objects), |
| 241 | + len(objects), |
| 242 | + ) |
| 243 | + self.assertEqual( |
| 244 | + connection.ops.bulk_batch_size( |
| 245 | + [first_name_field, last_name_field], objects |
| 246 | + ), |
| 247 | + len(objects), |
| 248 | + ) |
| 249 | + self.assertEqual( |
| 250 | + connection.ops.bulk_batch_size([composite_pk, first_name_field], objects), |
| 251 | + len(objects), |
| 252 | + ) |
| 253 | + |
204 | 254 |
|
205 | 255 | class SqlFlushTests(TransactionTestCase): |
206 | 256 | available_apps = ["backends"] |
|
0 commit comments