diff options
| author | Mikhail Nacharov <mnach@yandex.ru> | 2017-02-07 09:49:31 +0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2017-02-09 18:47:08 -0500 |
| commit | c4e2fc5d9872c9a0c9c052a2e124f8a9b87de9b4 (patch) | |
| tree | 530e98c87e77d6c3922aa545ef0d309d7e9dac51 /django | |
| parent | 965f678a39b79f8e0bdc8222df094916fd7f8ed4 (diff) | |
Fixed #22669 -- Fixed QuerySet.bulk_create() with empty model fields on Oracle.
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/backends/oracle/operations.py | 18 | ||||
| -rw-r--r-- | django/db/backends/oracle/utils.py | 24 |
2 files changed, 37 insertions, 5 deletions
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py index 7cc33af537..bf9834d1f8 100644 --- a/django/db/backends/oracle/operations.py +++ b/django/db/backends/oracle/operations.py @@ -9,7 +9,7 @@ from django.utils import timezone from django.utils.encoding import force_bytes, force_text from .base import Database -from .utils import InsertIdVar, Oracle_datetime +from .utils import BulkInsertMapper, InsertIdVar, Oracle_datetime class DatabaseOperations(BaseDatabaseOperations): @@ -523,10 +523,18 @@ WHEN (new.%(col_name)s IS NULL) return truncate_name(trigger_name, name_length).upper() def bulk_insert_sql(self, fields, placeholder_rows): - return " UNION ALL ".join( - "SELECT %s FROM DUAL" % ", ".join(row) - for row in placeholder_rows - ) + query = [] + for row in placeholder_rows: + select = [] + for i, placeholder in enumerate(row): + # A model without any fields has fields=[None]. + if not fields[i]: + select.append(placeholder) + else: + internal_type = getattr(fields[i], 'target_field', fields[i]).get_internal_type() + select.append(BulkInsertMapper.types.get(internal_type, '%s') % placeholder) + query.append('SELECT %s FROM DUAL' % ', '.join(select)) + return ' UNION ALL '.join(query) def subtract_temporals(self, internal_type, lhs, rhs): if internal_type == 'DateField': diff --git a/django/db/backends/oracle/utils.py b/django/db/backends/oracle/utils.py index f958655f94..6c81d5cd7b 100644 --- a/django/db/backends/oracle/utils.py +++ b/django/db/backends/oracle/utils.py @@ -29,3 +29,27 @@ class Oracle_datetime(datetime.datetime): dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, ) + + +class BulkInsertMapper: + BLOB = 'TO_BLOB(%s)' + DATE = 'TO_DATE(%s)' + INTERVAL = 'CAST(%s as INTERVAL DAY(9) TO SECOND(6))' + NUMBER = 'TO_NUMBER(%s)' + TIMESTAMP = 'TO_TIMESTAMP(%s)' + + types = { + 'BigIntegerField': NUMBER, + 'BinaryField': BLOB, + 'DateField': DATE, + 'DateTimeField': TIMESTAMP, + 'DecimalField': NUMBER, + 'DurationField': INTERVAL, + 'FloatField': NUMBER, + 'IntegerField': NUMBER, + 'NullBooleanField': NUMBER, + 'PositiveIntegerField': NUMBER, + 'PositiveSmallIntegerField': NUMBER, + 'SmallIntegerField': NUMBER, + 'TimeField': TIMESTAMP, + } |
