Opened 5 years ago
Last modified 4 years ago
#31731 closed Cleanup/optimization
Dead code in the sequence_reset_sql for postgres and oracle — at Initial Version
Reported by: | axil | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.0 |
Severity: | Normal | Keywords: | sql sequence reset postgres oracle |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In the definition of sequence_reset_sql
function in django/db/backends/postgresql/operations.py
and django/db/backends/oracle/operations.py
files
def sequence_reset_sql(self, style, model_list): from django.db import models output = [] qn = self.quote_name 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. # Use pg_get_serial_sequence to get the underlying sequence name from the table name # and column name (available since PostgreSQL 8) for f in model._meta.local_fields: if isinstance(f, models.AutoField): output.append( "%s setval(pg_get_serial_sequence('%s','%s'), " "coalesce(max(%s), 1), max(%s) %s null) %s %s;" % ( style.SQL_KEYWORD('SELECT'), style.SQL_TABLE(qn(model._meta.db_table)), style.SQL_FIELD(f.column), style.SQL_FIELD(qn(f.column)), style.SQL_FIELD(qn(f.column)), style.SQL_KEYWORD('IS NOT'), style.SQL_KEYWORD('FROM'), style.SQL_TABLE(qn(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: if not f.remote_field.through: ## output.append( ## "%s setval(pg_get_serial_sequence('%s','%s'), " ## "coalesce(max(%s), 1), max(%s) %s null) %s %s;" % ( ## style.SQL_KEYWORD('SELECT'), ## style.SQL_TABLE(qn(f.m2m_db_table())), ## style.SQL_FIELD('id'), ## style.SQL_FIELD(qn('id')), ## style.SQL_FIELD(qn('id')), ## style.SQL_KEYWORD('IS NOT'), ## style.SQL_KEYWORD('FROM'), ## style.SQL_TABLE(qn(f.m2m_db_table())) ## ) ## ) return output
The statement marked with ## never executes.
11 years ago when this code was written (ticket #11107) this if not f.remote_field.through:
was a valid way to check if the ManyToManyField
uses the user-provided intermediate through
table or not. Nowadays bool(f.remote_field.through)
always evaluates to True
, no matter if it is a user-provided or an automatic table.
But actually it is not necessary anymore. This function is used in three places in django code:
1) manage.py sqlsequencereset
uses
models = app_config.get_models(include_auto_created=True)
instead of the original
models = app_config.get_models()
which was there when this ticket 11107 was merged. So now it fetches both automatic and user-defined intermediate tables at the ealier stage, before going.
2) loaddata is unaffected by this branch of execution because it needs to reset the sequences solely of the models that are being loaded and not of any others. To be 100% sure I included the fixture from ticket 11107 as the testcase and it passes without entering into that execution branch.
3) django.contrib.sites.management.create_default_site
applies it to the Site model
sequence_sql = connections[using].ops.sequence_reset_sql(no_style(), [Site])
which has no manytomany keys, so it is unaffected.
I would suggest to remove the code marked with "##" and check for other usages of f.remote_field.through
for similar issues.