summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES7
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py2
-rw-r--r--lib/sqlalchemy/engine/default.py11
-rw-r--r--lib/sqlalchemy/sql/compiler.py6
-rw-r--r--test/dialect/test_mysql.py19
-rw-r--r--test/sql/test_constraints.py36
6 files changed, 63 insertions, 18 deletions
diff --git a/CHANGES b/CHANGES
index 8b555f5a8..ae1763028 100644
--- a/CHANGES
+++ b/CHANGES
@@ -60,6 +60,13 @@ CHANGES
indexes on columns with similar names still
have unique names. [ticket:1855]
+ - The generated index name also is based on
+ a "max index name length" attribute which is
+ separate from the "max identifier length" -
+ this to appease MySQL who has a max length
+ of 64 for index names, separate from their
+ overall max length of 255. [ticket:1412]
+
- mssql
- Fixed "default schema" query to work with
pymssql backend.
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index 1c61f47e1..a2d3748f3 100644
--- a/lib/sqlalchemy/dialects/mysql/base.py
+++ b/lib/sqlalchemy/dialects/mysql/base.py
@@ -1607,8 +1607,10 @@ class MySQLDialect(default.DefaultDialect):
name = 'mysql'
supports_alter = True
+
# identifiers are 64, however aliases can be 255...
max_identifier_length = 255
+ max_index_name_length = 64
supports_native_enum = True
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index 0724d1fb9..390094c7d 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -59,7 +59,18 @@ class DefaultDialect(base.Dialect):
# end Py2K
name = 'default'
+
+ # length at which to truncate
+ # any identifier.
max_identifier_length = 9999
+
+ # length at which to truncate
+ # the name of an index.
+ # Usually None to indicate
+ # 'use max_identifier_length'.
+ # thanks to MySQL, sigh
+ max_index_name_length = None
+
supports_sane_rowcount = True
supports_sane_multi_rowcount = True
dbapi_type_map = {}
diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py
index 0383f9690..fcff5e355 100644
--- a/lib/sqlalchemy/sql/compiler.py
+++ b/lib/sqlalchemy/sql/compiler.py
@@ -1182,8 +1182,10 @@ class DDLCompiler(engine.Compiled):
def _index_identifier(self, ident):
if isinstance(ident, sql._generated_label):
- if len(ident) > self.dialect.max_identifier_length:
- return ident[0:self.dialect.max_identifier_length - 8] + \
+ max = self.dialect.max_index_name_length or \
+ self.dialect.max_identifier_length
+ if len(ident) > max:
+ return ident[0:max - 8] + \
"_" + util.md5_hex(ident)[-4:]
else:
return ident
diff --git a/test/dialect/test_mysql.py b/test/dialect/test_mysql.py
index 791a93c6e..7c4cc2309 100644
--- a/test/dialect/test_mysql.py
+++ b/test/dialect/test_mysql.py
@@ -1212,7 +1212,24 @@ class SQLTest(TestBase, AssertsCompiledSQL):
self.assert_compile(
select([extract('milliseconds', t.c.col1)]),
"SELECT EXTRACT(millisecond FROM t.col1) AS anon_1 FROM t")
-
+
+ def test_too_long_index(self):
+ exp = 'ix_zyrenian_zyme_zyzzogeton_zyzzogeton_zyrenian_zyme_zyz_5cd2'
+ tname = 'zyrenian_zyme_zyzzogeton_zyzzogeton'
+ cname = 'zyrenian_zyme_zyzzogeton_zo'
+
+ t1 = Table(tname, MetaData(),
+ Column(cname, Integer, index=True),
+ )
+ ix1 = list(t1.indexes)[0]
+
+ self.assert_compile(
+ schema.CreateIndex(ix1),
+ "CREATE INDEX %s "
+ "ON %s (%s)" % (exp, tname, cname),
+ dialect=mysql.dialect()
+ )
+
def test_innodb_autoincrement(self):
t1 = Table('sometable', MetaData(), Column('assigned_id',
Integer(), primary_key=True, autoincrement=False),
diff --git a/test/sql/test_constraints.py b/test/sql/test_constraints.py
index 5624c0ec6..69f29a9bd 100644
--- a/test/sql/test_constraints.py
+++ b/test/sql/test_constraints.py
@@ -183,24 +183,30 @@ class ConstraintTest(TestBase, AssertsExecutionResults, AssertsCompiledSQL):
def test_too_long_idx_name(self):
dialect = testing.db.dialect.__class__()
- dialect.max_identifier_length = 22
- for tname, cname, exp in [
- ('sometable', 'this_name_is_too_long', 'ix_sometable_t_09aa'),
- ('sometable', 'this_name_alsois_long', 'ix_sometable_t_3cf1'),
- ]:
+ for max_ident, max_index in [(22, None), (256, 22)]:
+ dialect.max_identifier_length = max_ident
+ dialect.max_index_name_length = max_index
+
+ for tname, cname, exp in [
+ ('sometable', 'this_name_is_too_long', 'ix_sometable_t_09aa'),
+ ('sometable', 'this_name_alsois_long', 'ix_sometable_t_3cf1'),
+ ]:
- t1 = Table(tname, MetaData(),
- Column(cname, Integer, index=True),
- )
- ix1 = list(t1.indexes)[0]
+ t1 = Table(tname, MetaData(),
+ Column(cname, Integer, index=True),
+ )
+ ix1 = list(t1.indexes)[0]
- self.assert_compile(
- schema.CreateIndex(ix1),
- "CREATE INDEX %s "
- "ON %s (%s)" % (exp, tname, cname),
- dialect=dialect
- )
+ self.assert_compile(
+ schema.CreateIndex(ix1),
+ "CREATE INDEX %s "
+ "ON %s (%s)" % (exp, tname, cname),
+ dialect=dialect
+ )
+
+ dialect.max_identifier_length = 22
+ dialect.max_index_name_length = None
t1 = Table('t', MetaData(), Column('c', Integer))
assert_raises(