diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py index a95f535bdb..f1b0c09abd 100644 --- a/django/db/backends/base/operations.py +++ b/django/db/backends/base/operations.py @@ -364,7 +364,24 @@ class BaseDatabaseOperations: return the SQL and params to append to the INSERT query. The returned fragment should contain a format string to hold the appropriate column. """ - pass + 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), () + + def fetch_returned_insert_rows(self, cursor): + """ + Given a cursor object that has just performed an INSERT...RETURNING + statement into a table, return the tuple of returned data. + """ + return cursor.fetchall() def compiler(self, compiler_name): """ diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index 2d6185a2ca..7dfcd57958 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -148,13 +148,6 @@ class DatabaseOperations(BaseDatabaseOperations): else: return f"TIME({sql})", params - def fetch_returned_insert_rows(self, cursor): - """ - Given a cursor object that has just performed an INSERT...RETURNING - statement into a table, return the tuple of returned data. - """ - return cursor.fetchall() - def format_for_duration_arithmetic(self, sql): return "INTERVAL %s MICROSECOND" % sql @@ -182,20 +175,6 @@ class DatabaseOperations(BaseDatabaseOperations): return name # Quoting once is enough. return "`%s`" % name - def return_insert_columns(self, fields): - # MySQL 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), () - def sql_flush(self, style, tables, *, reset_sequences=False, allow_cascade=False): if not tables: return [] diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index a8c073e418..7cd868d789 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -155,13 +155,6 @@ class DatabaseOperations(BaseDatabaseOperations): return f"SELECT * FROM {placeholder_rows}" return super().bulk_insert_sql(fields, placeholder_rows) - def fetch_returned_insert_rows(self, cursor): - """ - Given a cursor object that has just performed an INSERT...RETURNING - statement into a table, return the tuple of returned data. - """ - return cursor.fetchall() - def lookup_cast(self, lookup_type, internal_type=None): lookup = "%s" # Cast text lookups to text to allow things like filter(x__contains=4) @@ -324,19 +317,6 @@ class DatabaseOperations(BaseDatabaseOperations): return cursor.query.decode() return None - def return_insert_columns(self, fields): - 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), () - if is_psycopg3: def adapt_integerfield_value(self, value, internal_type): diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py index 4a1693768c..1500ae28aa 100644 --- a/django/db/backends/sqlite3/operations.py +++ b/django/db/backends/sqlite3/operations.py @@ -84,13 +84,6 @@ class DatabaseOperations(BaseDatabaseOperations): """ return f"django_date_extract(%s, {sql})", (lookup_type.lower(), *params) - 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 @@ -399,20 +392,6 @@ class DatabaseOperations(BaseDatabaseOperations): return "INSERT OR IGNORE INTO" return super().insert_statement(on_conflict=on_conflict) - 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), () - def on_conflict_suffix_sql(self, fields, on_conflict, update_fields, unique_fields): if ( on_conflict == OnConflict.UPDATE