Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #21842: Remove redundant DatabaseFeatures.max_index_name_length

  • Loading branch information...
commit 9c4ad454d18816d418b0bd31be91fae16c795f15 1 parent d5df7a0
@andrewgodwin andrewgodwin authored
View
3  django/db/backends/__init__.py
@@ -654,9 +654,6 @@ class BaseDatabaseFeatures(object):
# Can we issue more than one ALTER COLUMN clause in an ALTER TABLE?
supports_combined_alters = False
- # What's the maximum length for index names?
- max_index_name_length = 63
-
# Does it support foreign keys?
supports_foreign_keys = True
View
1  django/db/backends/oracle/base.py
@@ -99,7 +99,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_sequence_reset = False
atomic_transactions = False
supports_combined_alters = False
- max_index_name_length = 30
nulls_order_largest = True
requires_literal_defaults = True
connection_persists_old_columns = True
View
9 django/db/backends/schema.py
@@ -769,17 +769,18 @@ def _create_index_name(self, model, column_names, suffix=""):
# Else generate the name for the index using a different algorithm
table_name = model._meta.db_table.replace('"', '').replace('.', '_')
index_unique_name = '_%x' % abs(hash((table_name, ','.join(column_names))))
+ max_length = self.connection.ops.max_name_length() or 200
@manfre Collaborator
manfre added a note

Why the magic number? All backends are required to implement ops.max_name_length().

@andrewgodwin Owner

No, they're not - the default impl returns None, and the docstring says, "Returns the maximum length of table and column names, or None if there is no limit.".

The SQLite backend doesn't override it and thus returns None; I added a default limit as I don't want us to make names that are actually unlimited in length for autogenerated indexes (but we shouldn't stop you manually picking table names that long, so we shouldn't change ops.max_name_length())

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
# If the index name is too long, truncate it
index_name = ('%s_%s%s%s' % (table_name, column_names[0], index_unique_name, suffix)).replace('"', '').replace('.', '_')
- if len(index_name) > self.connection.features.max_index_name_length:
+ if len(index_name) > max_length:
part = ('_%s%s%s' % (column_names[0], index_unique_name, suffix))
- index_name = '%s%s' % (table_name[:(self.connection.features.max_index_name_length - len(part))], part)
+ index_name = '%s%s' % (table_name[:(max_length - len(part))], part)
# It shouldn't start with an underscore (Oracle hates this)
if index_name[0] == "_":
index_name = index_name[1:]
# If it's STILL too long, just hash it down
- if len(index_name) > self.connection.features.max_index_name_length:
- index_name = hashlib.md5(force_bytes(index_name)).hexdigest()[:self.connection.features.max_index_name_length]
+ if len(index_name) > max_length:
+ index_name = hashlib.md5(force_bytes(index_name)).hexdigest()[:max_length]
@manfre Collaborator
manfre added a note

It's better to use django.db.backends.utils.truncate_name for consistency with how the rest of the backend shortens names.

index_name = truncate_name(index_name, max_length)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
# It can't start with a number on Oracle, so prepend D if we need to
if index_name[0].isdigit():
index_name = "D%s" % index_name[:-1]
@manfre

Why the magic number? All backends are required to implement ops.max_name_length().

@andrewgodwin

No, they're not - the default impl returns None, and the docstring says, "Returns the maximum length of table and column names, or None if there is no limit.".

The SQLite backend doesn't override it and thus returns None; I added a default limit as I don't want us to make names that are actually unlimited in length for autogenerated indexes (but we shouldn't stop you manually picking table names that long, so we shouldn't change ops.max_name_length())

@manfre

It's better to use django.db.backends.utils.truncate_name for consistency with how the rest of the backend shortens names.

index_name = truncate_name(index_name, max_length)

Please sign in to comment.
Something went wrong with that request. Please try again.