Opened 11 years ago
Closed 11 years ago
#22670 closed Bug (duplicate)
bulk_create with empty model fields fails on oracle
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.6 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I did the minimal example for reproducing this bug. Model looks very simple:
class ProbaModel(models.Model): num = models.IntegerField(null=True, blank=True)
When i tried to run the following test code:
class ProbaTestCase(TestCase): def test_bulk_create(self): ProbaModel.objects.bulk_create( [ ProbaModel(num=1), ProbaModel() ] )
I got an
Traceback (most recent call last): File "/home/sns/devel/proba/proba/app1/tests.py", line 10, in test_bulk_create ProbaModel() File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/models/manager.py", line 160, in bulk_create return self.get_queryset().bulk_create(*args, **kwargs) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/models/query.py", line 359, in bulk_create self._batched_insert(objs_without_pk, fields, batch_size) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/models/query.py", line 838, in _batched_insert using=self.db) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/models/manager.py", line 232, in _insert return insert_query(self.model, objs, fields, **kwargs) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/models/query.py", line 1514, in insert_query return query.get_compiler(using=using).execute_sql(return_id) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 903, in execute_sql cursor.execute(sql, params) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute return self.cursor.execute(sql, params) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/utils.py", line 99, in __exit__ six.reraise(dj_exc_type, dj_exc_value, traceback) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/backends/util.py", line 53, in execute return self.cursor.execute(sql, params) File "/home/sns/devel/proba/local/lib/python2.7/site-packages/django/db/backends/oracle/base.py", line 816, in execute return self.cursor.execute(query, self._param_generator(params)) DatabaseError: ORA-01790: expression must have same datatype as corresponding expression
This bug confirmed on Oracle 11.2.0.4 and 12. Complete project located on my GitHub: https://github.com/nsadovskiy/bulk_create_fail
Solution that works fo me is patch on django/db/backends/oracle/base.py:
*** base.py 2014-05-20 18:37:07.000000000 +0700 --- base.py 2014-05-20 18:41:45.000000000 +0700 *************** *** 467,509 **** return '%s_TR' % util.truncate_name(table, name_length).upper() def bulk_insert_sql(self, fields, num_values): ! MAPPER = { ! 'CharField': 'to_nchar(%s)', ! 'CommaSeparatedIntegerField': 'to_nchar(%s)', ! 'EmailField': 'to_nchar(%s)', ! 'FileField': 'to_nchar(%s)', ! 'FilePathField': 'to_nchar(%s)', ! 'ImageField': 'to_nchar(%s)', ! 'SlugField': 'to_nchar(%s)', ! 'URLField': 'to_nchar(%s)', ! ! 'IPAddressField': 'to_char(%s)', ! 'GenericIPAddressField': 'to_char(%s)', ! ! 'AutoField': 'to_number(%s)', ! 'BigIntegerField': 'to_number(%s)', ! 'BooleanField': 'to_number(%s)', ! 'DecimalField': 'to_number(%s)', ! 'FloatField': 'to_number(%s)', ! 'IntegerField': 'to_number(%s)', ! 'NullBooleanField': 'to_number(%s)', ! 'PositiveIntegerField': 'to_number(%s)', ! 'PositiveSmallIntegerField': 'to_number(%s)', ! 'SmallIntegerField': 'to_number(%s)', ! 'ForeignKey': 'to_number(%s)', ! 'ManyToManyField': 'to_number(%s)', ! 'OneToOneField': 'to_number(%s)', ! ! 'DateField': 'to_date(%s)', ! ! 'DateTimeField': 'to_timestamp(%s)', ! 'TimeField': 'to_timestamp(%s)', ! ! 'BinaryField': 'to_blob(%s)', ! ! 'TextField': 'to_nclob(%s)' ! } ! items_sql = "SELECT %s FROM DUAL" % ", ".join([MAPPER.get(field.get_internal_type(), '%s') for field in fields]) return " UNION ALL ".join([items_sql] * num_values) --- 467,473 ---- return '%s_TR' % util.truncate_name(table, name_length).upper() def bulk_insert_sql(self, fields, num_values): ! items_sql = "SELECT %s FROM DUAL" % ", ".join(["%s"] * len(fields)) return " UNION ALL ".join([items_sql] * num_values)
Note:
See TracTickets
for help on using tickets.
Double post of #22669.