mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #31301 -- Fixed crash of QuerySet.bulk_create() with mixed empty and set ForeignKeys to AutoFields on Oracle.
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							8b30360322
						
					
				
				
					commit
					a21f7b91db
				
			| @@ -62,6 +62,8 @@ class BulkInsertMapper: | ||||
|     TIMESTAMP = 'TO_TIMESTAMP(%s)' | ||||
|  | ||||
|     types = { | ||||
|         'AutoField': NUMBER, | ||||
|         'BigAutoField': NUMBER, | ||||
|         'BigIntegerField': NUMBER, | ||||
|         'BinaryField': BLOB, | ||||
|         'BooleanField': NUMBER, | ||||
| @@ -75,6 +77,7 @@ class BulkInsertMapper: | ||||
|         'PositiveBigIntegerField': NUMBER, | ||||
|         'PositiveIntegerField': NUMBER, | ||||
|         'PositiveSmallIntegerField': NUMBER, | ||||
|         'SmallAutoField': NUMBER, | ||||
|         'SmallIntegerField': NUMBER, | ||||
|         'TextField': CLOB, | ||||
|         'TimeField': TIMESTAMP, | ||||
|   | ||||
| @@ -64,6 +64,14 @@ class NoFields(models.Model): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class SmallAutoFieldModel(models.Model): | ||||
|     id = models.SmallAutoField(primary_key=True) | ||||
|  | ||||
|  | ||||
| class BigAutoFieldModel(models.Model): | ||||
|     id = models.BigAutoField(primary_key=True) | ||||
|  | ||||
|  | ||||
| class NullableFields(models.Model): | ||||
|     # Fields in db.backends.oracle.BulkInsertMapper | ||||
|     big_int_filed = models.BigIntegerField(null=True, default=1) | ||||
| @@ -81,6 +89,9 @@ class NullableFields(models.Model): | ||||
|     positive_small_integer_field = models.PositiveSmallIntegerField(null=True, default=4) | ||||
|     small_integer_field = models.SmallIntegerField(null=True, default=5) | ||||
|     time_field = models.TimeField(null=True, default=timezone.now) | ||||
|     auto_field = models.ForeignKey(NoFields, on_delete=models.CASCADE, null=True) | ||||
|     small_auto_field = models.ForeignKey(SmallAutoFieldModel, on_delete=models.CASCADE, null=True) | ||||
|     big_auto_field = models.ForeignKey(BigAutoFieldModel, on_delete=models.CASCADE, null=True) | ||||
|     # Fields not required in BulkInsertMapper | ||||
|     char_field = models.CharField(null=True, max_length=4, default='char') | ||||
|     email_field = models.EmailField(null=True, default='user@example.com') | ||||
|   | ||||
| @@ -9,9 +9,9 @@ from django.test import ( | ||||
| ) | ||||
|  | ||||
| from .models import ( | ||||
|     Country, NoFields, NullableFields, Pizzeria, ProxyCountry, | ||||
|     ProxyMultiCountry, ProxyMultiProxyCountry, ProxyProxyCountry, Restaurant, | ||||
|     State, TwoFields, | ||||
|     BigAutoFieldModel, Country, NoFields, NullableFields, Pizzeria, | ||||
|     ProxyCountry, ProxyMultiCountry, ProxyMultiProxyCountry, ProxyProxyCountry, | ||||
|     Restaurant, SmallAutoFieldModel, State, TwoFields, | ||||
| ) | ||||
|  | ||||
|  | ||||
| @@ -234,10 +234,16 @@ class BulkCreateTests(TestCase): | ||||
|  | ||||
|     @skipUnlessDBFeature('has_bulk_insert') | ||||
|     def test_bulk_insert_nullable_fields(self): | ||||
|         fk_to_auto_fields = { | ||||
|             'auto_field': NoFields.objects.create(), | ||||
|             'small_auto_field': SmallAutoFieldModel.objects.create(), | ||||
|             'big_auto_field': BigAutoFieldModel.objects.create(), | ||||
|         } | ||||
|         # NULL can be mixed with other values in nullable fields | ||||
|         nullable_fields = [field for field in NullableFields._meta.get_fields() if field.name != 'id'] | ||||
|         NullableFields.objects.bulk_create([ | ||||
|             NullableFields(**{field.name: None}) for field in nullable_fields | ||||
|             NullableFields(**{**fk_to_auto_fields, field.name: None}) | ||||
|             for field in nullable_fields | ||||
|         ]) | ||||
|         self.assertEqual(NullableFields.objects.count(), len(nullable_fields)) | ||||
|         for field in nullable_fields: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user