Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

Fixed #21842: Remove redundant DatabaseFeatures.max_index_name_length

  • Loading branch information...
1 parent d5df7a0 commit 9c4ad454d18816d418b0bd31be91fae16c795f15 @andrewgodwin andrewgodwin committed
3  django/db/backends/
@@ -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
1  django/db/backends/oracle/
@@ -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
9 django/db/backends/
@@ -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]

0 comments on commit 9c4ad45

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