From: Mike Bayer Date: Mon, 2 Aug 2010 05:12:03 +0000 (-0400) Subject: - The generated index name also is based on X-Git-Tag: rel_0_6_4~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b2c0b50bbfa43f662afd16b7ca51bcfe17e4c351;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - 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] --- diff --git a/CHANGES b/CHANGES index 8b555f5a83..ae17630283 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 1c61f47e18..a2d3748f33 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 0724d1fb97..390094c7de 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 0383f9690f..fcff5e3550 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 791a93c6e6..7c4cc2309f 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 5624c0ec6d..69f29a9bd4 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(