Fixed #32501 -- Added support for returning fields from INSERT statements on SQLite 3.35+.

This commit is contained in:
girishsontakke 2021-04-06 21:50:31 +05:30 committed by Mariusz Felisiak
parent 3f2920ae1d
commit 98abc0c90e
4 changed files with 34 additions and 1 deletions

View File

@ -117,3 +117,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
can_introspect_json_field = property(operator.attrgetter('supports_json_field'))
has_json_object_function = property(operator.attrgetter('supports_json_field'))
@cached_property
def can_return_columns_from_insert(self):
return Database.sqlite_version_info >= (3, 35)
can_return_rows_from_bulk_insert = property(operator.attrgetter('can_return_columns_from_insert'))

View File

@ -76,6 +76,13 @@ class DatabaseOperations(BaseDatabaseOperations):
"""
return "django_date_extract('%s', %s)" % (lookup_type.lower(), field_name)
def fetch_returned_insert_rows(self, cursor):
"""
Given a cursor object that has just performed an INSERT...RETURNING
statement into a table, return the list of returned data.
"""
return cursor.fetchall()
def format_for_duration_arithmetic(self, sql):
"""Do nothing since formatting is handled in the custom function."""
return sql
@ -365,3 +372,15 @@ class DatabaseOperations(BaseDatabaseOperations):
def insert_statement(self, ignore_conflicts=False):
return 'INSERT OR IGNORE INTO' if ignore_conflicts else super().insert_statement(ignore_conflicts)
def return_insert_columns(self, fields):
# SQLite < 3.35 doesn't support an INSERT...RETURNING statement.
if not fields:
return '', ()
columns = [
'%s.%s' % (
self.quote_name(field.model._meta.db_table),
self.quote_name(field.column),
) for field in fields
]
return 'RETURNING %s' % ', '.join(columns), ()

View File

@ -2171,7 +2171,8 @@ This has a number of caveats though:
* It does not work with child models in a multi-table inheritance scenario.
* If the model's primary key is an :class:`~django.db.models.AutoField`, the
primary key attribute can only be retrieved on certain databases (currently
PostgreSQL and MariaDB 10.5+). On other databases, it will not be set.
PostgreSQL, MariaDB 10.5+, and SQLite 3.35+). On other databases, it will not
be set.
* It does not work with many-to-many relationships.
* It casts ``objs`` to a list, which fully evaluates ``objs`` if it's a
generator. The cast allows inspecting all objects so that any objects with a
@ -2210,6 +2211,10 @@ normally supports it).
.. _MySQL documentation: https://dev.mysql.com/doc/refman/en/sql-mode.html#ignore-strict-comparison
.. _MariaDB documentation: https://mariadb.com/kb/en/ignore/
.. versionchanged:: 4.0
Support for the fetching primary key attributes on SQLite 3.35+ was added.
``bulk_update()``
~~~~~~~~~~~~~~~~~

View File

@ -230,6 +230,9 @@ Models
:class:`Round() <django.db.models.functions.Round>` database function allows
specifying the number of decimal places after rounding.
* :meth:`.QuerySet.bulk_create` now sets the primary key on objects when using
SQLite 3.35+.
Requests and Responses
~~~~~~~~~~~~~~~~~~~~~~