Fixed #31275 -- Optimized sql_flush() without resetting sequences on MySQL.
Co-Authored-By: Simon Charette <charettes@users.noreply.github.com>
This commit is contained in:
parent
75520e1767
commit
89032876f4
1
AUTHORS
1
AUTHORS
|
@ -585,6 +585,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Martin von Gagern <gagern@google.com>
|
Martin von Gagern <gagern@google.com>
|
||||||
Mart Sõmermaa <http://mrts.pri.ee/>
|
Mart Sõmermaa <http://mrts.pri.ee/>
|
||||||
Marty Alchin <gulopine@gamemusic.org>
|
Marty Alchin <gulopine@gamemusic.org>
|
||||||
|
Masashi Shibata <m.shibata1020@gmail.com>
|
||||||
masonsimon+django@gmail.com
|
masonsimon+django@gmail.com
|
||||||
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
Massimiliano Ravelli <massimiliano.ravelli@gmail.com>
|
||||||
Massimo Scamarcia <massimo.scamarcia@gmail.com>
|
Massimo Scamarcia <massimo.scamarcia@gmail.com>
|
||||||
|
|
|
@ -194,21 +194,40 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
return 'RETURNING %s' % ', '.join(columns), ()
|
return 'RETURNING %s' % ', '.join(columns), ()
|
||||||
|
|
||||||
def sql_flush(self, style, tables, sequences, allow_cascade=False):
|
def sql_flush(self, style, tables, sequences, allow_cascade=False):
|
||||||
# NB: The generated SQL below is specific to MySQL
|
if not tables:
|
||||||
# 'TRUNCATE x;', 'TRUNCATE y;', 'TRUNCATE z;'... style SQL statements
|
|
||||||
# to clear all tables of all data
|
|
||||||
if tables:
|
|
||||||
sql = ['SET FOREIGN_KEY_CHECKS = 0;']
|
|
||||||
for table in tables:
|
|
||||||
sql.append('%s %s;' % (
|
|
||||||
style.SQL_KEYWORD('TRUNCATE'),
|
|
||||||
style.SQL_FIELD(self.quote_name(table)),
|
|
||||||
))
|
|
||||||
sql.append('SET FOREIGN_KEY_CHECKS = 1;')
|
|
||||||
sql.extend(self.sequence_reset_by_name_sql(style, sequences))
|
|
||||||
return sql
|
|
||||||
else:
|
|
||||||
return []
|
return []
|
||||||
|
sql = ['SET FOREIGN_KEY_CHECKS = 0;']
|
||||||
|
tables = set(tables)
|
||||||
|
with_sequences = set(s['table'] for s in sequences)
|
||||||
|
# It's faster to TRUNCATE tables that require a sequence reset since
|
||||||
|
# ALTER TABLE AUTO_INCREMENT is slower than TRUNCATE.
|
||||||
|
sql.extend(
|
||||||
|
'%s %s;' % (
|
||||||
|
style.SQL_KEYWORD('TRUNCATE'),
|
||||||
|
style.SQL_FIELD(self.quote_name(table_name)),
|
||||||
|
) for table_name in tables.intersection(with_sequences)
|
||||||
|
)
|
||||||
|
# Otherwise issue a simple DELETE since it's faster than TRUNCATE
|
||||||
|
# and preserves sequences.
|
||||||
|
sql.extend(
|
||||||
|
'%s %s %s;' % (
|
||||||
|
style.SQL_KEYWORD('DELETE'),
|
||||||
|
style.SQL_KEYWORD('FROM'),
|
||||||
|
style.SQL_FIELD(self.quote_name(table_name)),
|
||||||
|
) for table_name in tables.difference(with_sequences)
|
||||||
|
)
|
||||||
|
sql.append('SET FOREIGN_KEY_CHECKS = 1;')
|
||||||
|
return sql
|
||||||
|
|
||||||
|
def sequence_reset_by_name_sql(self, style, sequences):
|
||||||
|
return [
|
||||||
|
'%s %s %s %s = 1;' % (
|
||||||
|
style.SQL_KEYWORD('ALTER'),
|
||||||
|
style.SQL_KEYWORD('TABLE'),
|
||||||
|
style.SQL_FIELD(self.quote_name(sequence_info['table'])),
|
||||||
|
style.SQL_FIELD('AUTO_INCREMENT'),
|
||||||
|
) for sequence_info in sequences
|
||||||
|
]
|
||||||
|
|
||||||
def validate_autopk_value(self, value):
|
def validate_autopk_value(self, value):
|
||||||
# MySQLism: zero in AUTO_INCREMENT field does not work. Refs #17653.
|
# MySQLism: zero in AUTO_INCREMENT field does not work. Refs #17653.
|
||||||
|
|
|
@ -347,6 +347,10 @@ Models
|
||||||
* :meth:`.QuerySet.bulk_create` now sets the primary key on objects when using
|
* :meth:`.QuerySet.bulk_create` now sets the primary key on objects when using
|
||||||
MariaDB 10.5+.
|
MariaDB 10.5+.
|
||||||
|
|
||||||
|
* The ``DatabaseOperations.sql_flush()`` method now generates more efficient
|
||||||
|
SQL on MySQL by using ``DELETE`` instead of ``TRUNCATE`` statements for
|
||||||
|
tables which don't require resetting sequences.
|
||||||
|
|
||||||
Pagination
|
Pagination
|
||||||
~~~~~~~~~~
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -415,6 +419,12 @@ Tests
|
||||||
* :class:`~django.test.runner.DiscoverRunner` now skips running the system
|
* :class:`~django.test.runner.DiscoverRunner` now skips running the system
|
||||||
checks on databases not :ref:`referenced by tests<testing-multi-db>`.
|
checks on databases not :ref:`referenced by tests<testing-multi-db>`.
|
||||||
|
|
||||||
|
* :class:`~django.test.TransactionTestCase` teardown is now faster on MySQL
|
||||||
|
due to :djadmin:`flush` command improvements. As a side effect the latter
|
||||||
|
doesn't automatically reset sequences on teardown anymore. Enable
|
||||||
|
:attr:`.TransactionTestCase.reset_sequences` if your tests require this
|
||||||
|
feature.
|
||||||
|
|
||||||
URLs
|
URLs
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue