diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 82b8968c61..4cbdb55c67 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -15,7 +15,7 @@ class Command(BaseCommand): def handle(self, *fixture_labels, **options): from django.db.models import get_apps from django.core import serializers - from django.db import connection, transaction, backend + from django.db import connection, transaction from django.conf import settings self.style = no_style() @@ -105,7 +105,7 @@ class Command(BaseCommand): (format, fixture_name, humanize(fixture_dir)) if count[0] > 0: - sequence_sql = backend.get_sql_sequence_reset(self.style, models) + sequence_sql = connection.ops.sequence_reset_sql(self.style, models) if sequence_sql: if verbosity > 1: print "Resetting sequences" diff --git a/django/core/management/commands/sqlsequencereset.py b/django/core/management/commands/sqlsequencereset.py index 8ed2fbaf97..6b12d83843 100644 --- a/django/core/management/commands/sqlsequencereset.py +++ b/django/core/management/commands/sqlsequencereset.py @@ -5,5 +5,5 @@ class Command(AppCommand): output_transaction = True def handle_app(self, app, **options): - from django.db import backend, models - return '\n'.join(backend.get_sql_sequence_reset(self.style, models.get_models(app))) + from django.db import connection, models + return '\n'.join(connection.ops.sequence_reset_sql(self.style, models.get_models(app))) diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py index e1122344ec..07a645307f 100644 --- a/django/db/backends/__init__.py +++ b/django/db/backends/__init__.py @@ -150,3 +150,13 @@ class BaseDatabaseOperations(object): color_style() or no_style() in django.core.management.color. """ raise NotImplementedError() + + def sequence_reset_sql(self, style, model_list): + """ + Returns a list of the SQL statements required to reset sequences for + the given models. + + The `style` argument is a Style object as returned by either + color_style() or no_style() in django.core.management.color. + """ + return [] # No sequence reset required by default. diff --git a/django/db/backends/ado_mssql/base.py b/django/db/backends/ado_mssql/base.py index f514905528..478ad9afda 100644 --- a/django/db/backends/ado_mssql/base.py +++ b/django/db/backends/ado_mssql/base.py @@ -109,11 +109,6 @@ def get_start_transaction_sql(): def get_tablespace_sql(tablespace, inline=False): return "ON %s" % quote_name(tablespace) -def get_sql_sequence_reset(style, model_list): - "Returns a list of the SQL statements to reset sequences for the given models." - # No sequence reset required - return [] - OPERATOR_MAPPING = { 'exact': '= %s', 'iexact': 'LIKE %s', diff --git a/django/db/backends/dummy/base.py b/django/db/backends/dummy/base.py index 19534423ca..4bc965ac43 100644 --- a/django/db/backends/dummy/base.py +++ b/django/db/backends/dummy/base.py @@ -44,6 +44,5 @@ dictfetchone = complain dictfetchmany = complain dictfetchall = complain get_start_transaction_sql = complain -get_sql_sequence_reset = complain OPERATOR_MAPPING = {} diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index e09313c585..6096700296 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -191,11 +191,6 @@ dictfetchall = util.dictfetchall def get_start_transaction_sql(): return "BEGIN;" -def get_sql_sequence_reset(style, model_list): - "Returns a list of the SQL statements to reset sequences for the given models." - # No sequence reset required - return [] - OPERATOR_MAPPING = { 'exact': '= %s', 'iexact': 'LIKE %s', diff --git a/django/db/backends/mysql_old/base.py b/django/db/backends/mysql_old/base.py index 38533d5aa0..babf805304 100644 --- a/django/db/backends/mysql_old/base.py +++ b/django/db/backends/mysql_old/base.py @@ -210,11 +210,6 @@ dictfetchall = util.dictfetchall def get_start_transaction_sql(): return "BEGIN;" -def get_sql_sequence_reset(style, model_list): - "Returns a list of the SQL statements to reset sequences for the given models." - # No sequence reset required - return [] - OPERATOR_MAPPING = { 'exact': '= %s', 'iexact': 'LIKE %s', diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index 9fb79bf949..9d9305d3f8 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -95,6 +95,23 @@ class DatabaseOperations(BaseDatabaseOperations): else: return [] + def sequence_reset_sql(self, style, model_list): + from django.db import models + output = [] + query = _get_sequence_reset_sql() + for model in model_list: + for f in model._meta.fields: + if isinstance(f, models.AutoField): + sequence_name = get_sequence_name(model._meta.db_table) + output.append(query % {'sequence':sequence_name, + 'table':model._meta.db_table}) + break # Only one AutoField is allowed per model, so don't bother continuing. + for f in model._meta.many_to_many: + sequence_name = get_sequence_name(f.m2m_db_table()) + output.append(query % {'sequence':sequence_name, + 'table':f.m2m_db_table()}) + return output + class DatabaseWrapper(BaseDatabaseWrapper): ops = DatabaseOperations() @@ -244,24 +261,6 @@ def get_sequence_name(table): name_length = DatabaseOperations().max_name_length() - 3 return '%s_SQ' % util.truncate_name(table, name_length).upper() -def get_sql_sequence_reset(style, model_list): - "Returns a list of the SQL statements to reset sequences for the given models." - from django.db import models - output = [] - query = _get_sequence_reset_sql() - for model in model_list: - for f in model._meta.fields: - if isinstance(f, models.AutoField): - sequence_name = get_sequence_name(model._meta.db_table) - output.append(query % {'sequence':sequence_name, - 'table':model._meta.db_table}) - break # Only one AutoField is allowed per model, so don't bother continuing. - for f in model._meta.many_to_many: - sequence_name = get_sequence_name(f.m2m_db_table()) - output.append(query % {'sequence':sequence_name, - 'table':f.m2m_db_table()}) - return output - def get_trigger_name(table): name_length = DatabaseOperations().max_name_length() - 3 return '%s_TR' % util.truncate_name(table, name_length).upper() diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index d3ad270aac..1ff5003129 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -124,6 +124,35 @@ class DatabaseOperations(BaseDatabaseOperations): else: return [] + def sequence_reset_sql(self, style, model_list): + from django.db import models + output = [] + for model in model_list: + # Use `coalesce` to set the sequence for each model to the max pk value if there are records, + # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true + # if there are records (as the max pk value is already in use), otherwise set it to false. + for f in model._meta.fields: + if isinstance(f, models.AutoField): + output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ + (style.SQL_KEYWORD('SELECT'), + style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))), + style.SQL_FIELD(quote_name(f.column)), + style.SQL_FIELD(quote_name(f.column)), + style.SQL_KEYWORD('IS NOT'), + style.SQL_KEYWORD('FROM'), + style.SQL_TABLE(quote_name(model._meta.db_table)))) + break # Only one AutoField is allowed per model, so don't bother continuing. + for f in model._meta.many_to_many: + output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ + (style.SQL_KEYWORD('SELECT'), + style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())), + style.SQL_FIELD(quote_name('id')), + style.SQL_FIELD(quote_name('id')), + style.SQL_KEYWORD('IS NOT'), + style.SQL_KEYWORD('FROM'), + style.SQL_TABLE(f.m2m_db_table()))) + return output + class DatabaseWrapper(BaseDatabaseWrapper): ops = DatabaseOperations() @@ -185,36 +214,6 @@ def dictfetchall(cursor): def get_start_transaction_sql(): return "BEGIN;" -def get_sql_sequence_reset(style, model_list): - "Returns a list of the SQL statements to reset sequences for the given models." - from django.db import models - output = [] - for model in model_list: - # Use `coalesce` to set the sequence for each model to the max pk value if there are records, - # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true - # if there are records (as the max pk value is already in use), otherwise set it to false. - for f in model._meta.fields: - if isinstance(f, models.AutoField): - output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ - (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))), - style.SQL_FIELD(quote_name(f.column)), - style.SQL_FIELD(quote_name(f.column)), - style.SQL_KEYWORD('IS NOT'), - style.SQL_KEYWORD('FROM'), - style.SQL_TABLE(quote_name(model._meta.db_table)))) - break # Only one AutoField is allowed per model, so don't bother continuing. - for f in model._meta.many_to_many: - output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ - (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())), - style.SQL_FIELD(quote_name('id')), - style.SQL_FIELD(quote_name('id')), - style.SQL_KEYWORD('IS NOT'), - style.SQL_KEYWORD('FROM'), - style.SQL_TABLE(f.m2m_db_table()))) - return output - def typecast_string(s): """ Cast all returned strings to unicode strings. diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py index 17df019a01..ac1c5a2a55 100644 --- a/django/db/backends/postgresql_psycopg2/base.py +++ b/django/db/backends/postgresql_psycopg2/base.py @@ -86,6 +86,35 @@ class DatabaseOperations(BaseDatabaseOperations): else: return [] + def sequence_reset_sql(self, style, model_list): + from django.db import models + output = [] + for model in model_list: + # Use `coalesce` to set the sequence for each model to the max pk value if there are records, + # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true + # if there are records (as the max pk value is already in use), otherwise set it to false. + for f in model._meta.fields: + if isinstance(f, models.AutoField): + output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ + (style.SQL_KEYWORD('SELECT'), + style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))), + style.SQL_FIELD(quote_name(f.column)), + style.SQL_FIELD(quote_name(f.column)), + style.SQL_KEYWORD('IS NOT'), + style.SQL_KEYWORD('FROM'), + style.SQL_TABLE(quote_name(model._meta.db_table)))) + break # Only one AutoField is allowed per model, so don't bother continuing. + for f in model._meta.many_to_many: + output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ + (style.SQL_KEYWORD('SELECT'), + style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())), + style.SQL_FIELD(quote_name('id')), + style.SQL_FIELD(quote_name('id')), + style.SQL_KEYWORD('IS NOT'), + style.SQL_KEYWORD('FROM'), + style.SQL_TABLE(f.m2m_db_table()))) + return output + class DatabaseWrapper(BaseDatabaseWrapper): ops = DatabaseOperations() @@ -139,36 +168,6 @@ dictfetchall = util.dictfetchall def get_start_transaction_sql(): return "BEGIN;" -def get_sql_sequence_reset(style, model_list): - "Returns a list of the SQL statements to reset sequences for the given models." - from django.db import models - output = [] - for model in model_list: - # Use `coalesce` to set the sequence for each model to the max pk value if there are records, - # or 1 if there are none. Set the `is_called` property (the third argument to `setval`) to true - # if there are records (as the max pk value is already in use), otherwise set it to false. - for f in model._meta.fields: - if isinstance(f, models.AutoField): - output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ - (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(quote_name('%s_%s_seq' % (model._meta.db_table, f.column))), - style.SQL_FIELD(quote_name(f.column)), - style.SQL_FIELD(quote_name(f.column)), - style.SQL_KEYWORD('IS NOT'), - style.SQL_KEYWORD('FROM'), - style.SQL_TABLE(quote_name(model._meta.db_table)))) - break # Only one AutoField is allowed per model, so don't bother continuing. - for f in model._meta.many_to_many: - output.append("%s setval('%s', coalesce(max(%s), 1), max(%s) %s null) %s %s;" % \ - (style.SQL_KEYWORD('SELECT'), - style.SQL_FIELD(quote_name('%s_id_seq' % f.m2m_db_table())), - style.SQL_FIELD(quote_name('id')), - style.SQL_FIELD(quote_name('id')), - style.SQL_KEYWORD('IS NOT'), - style.SQL_KEYWORD('FROM'), - style.SQL_TABLE(f.m2m_db_table()))) - return output - OPERATOR_MAPPING = { 'exact': '= %s', 'iexact': 'ILIKE %s', diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py index ce3a0e719a..3c35cb200d 100644 --- a/django/db/backends/sqlite3/base.py +++ b/django/db/backends/sqlite3/base.py @@ -134,11 +134,6 @@ def _sqlite_extract(lookup_type, dt): def get_start_transaction_sql(): return "BEGIN;" -def get_sql_sequence_reset(style, model_list): - "Returns a list of the SQL statements to reset sequences for the given models." - # No sequence reset required - return [] - def _sqlite_date_trunc(lookup_type, dt): try: dt = util.typecast_timestamp(dt)