From: Mike Bayer Date: Mon, 22 Feb 2010 19:28:25 +0000 (+0000) Subject: - Composite PK table on InnoDB where the "autoincrement" column X-Git-Tag: rel_0_6beta2~157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4460f998e3b856e94e870c08cb4ed357027ced00;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Composite PK table on InnoDB where the "autoincrement" column isn't first will emit an explicit "KEY" phrase within CREATE TABLE thereby avoiding errors, [ticket:1496] --- diff --git a/CHANGES b/CHANGES index e8582ebf65..41761c207f 100644 --- a/CHANGES +++ b/CHANGES @@ -146,6 +146,10 @@ CHANGES - Further fixes for the mysql-connector dialect. [ticket:1668] + - Composite PK table on InnoDB where the "autoincrement" column + isn't first will emit an explicit "KEY" phrase within + CREATE TABLE thereby avoiding errors, [ticket:1496] + - mssql - Re-established initial support for pymssql. diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index 686e3da627..4a4648076c 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -1269,6 +1269,26 @@ class MySQLCompiler(compiler.SQLCompiler): # creation of foreign key constraints fails." class MySQLDDLCompiler(compiler.DDLCompiler): + def create_table_constraints(self, table): + """Get table constraints.""" + constraint_string = super(MySQLDDLCompiler, self).create_table_constraints(table) + + is_innodb = table.kwargs.has_key('mysql_engine') and \ + table.kwargs['mysql_engine'].lower() == 'innodb' + + auto_inc_column = table._autoincrement_column + + if is_innodb and \ + auto_inc_column is not None and \ + auto_inc_column is not list(table.primary_key)[0]: + if constraint_string: + constraint_string += ", \n\t" + constraint_string += "KEY `idx_autoinc_%s`(`%s`)" % (auto_inc_column.name, \ + self.preparer.format_column(auto_inc_column)) + + return constraint_string + + def get_column_specification(self, column, **kw): """Builds column DDL.""" diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 187b4d26f0..32aa2a9920 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1004,17 +1004,26 @@ class DDLCompiler(engine.Compiled): if const: text += " " + const + const = self.create_table_constraints(table) + if const: + text += ", \n\t" + const + + text += "\n)%s\n\n" % self.post_create_table(table) + return text + + def create_table_constraints(self, table): + # On some DB order is significant: visit PK first, then the # other constraints (engine.ReflectionTest.testbasic failed on FB2) + constraints = [] if table.primary_key: - pk = self.process(table.primary_key) - if pk: - text += ", \n\t" + pk + constraints.append(table.primary_key) + + constraints.extend([c for c in table.constraints if c is not table.primary_key]) - const = ", \n\t".join(p for p in - (self.process(constraint) for constraint in table.constraints - if constraint is not table.primary_key - and ( + return ", \n\t".join(p for p in + (self.process(constraint) for constraint in constraints + if ( constraint._create_rule is None or constraint._create_rule(self)) and ( @@ -1022,11 +1031,6 @@ class DDLCompiler(engine.Compiled): not getattr(constraint, 'use_alter', False) )) if p is not None ) - if const: - text += ", \n\t" + const - - text += "\n)%s\n\n" % self.post_create_table(table) - return text def visit_drop_table(self, drop): ret = "\nDROP TABLE " + self.preparer.format_table(drop.element) diff --git a/test/dialect/test_mysql.py b/test/dialect/test_mysql.py index 9fe859f1db..1bfaef317f 100644 --- a/test/dialect/test_mysql.py +++ b/test/dialect/test_mysql.py @@ -1123,6 +1123,38 @@ class SQLTest(TestBase, AssertsCompiledSQL): select([extract('milliseconds', t.c.col1)]), "SELECT EXTRACT(millisecond FROM t.col1) AS anon_1 FROM t") + def test_innodb_autoincrement(self): + t1 = Table('sometable', MetaData(), + Column('assigned_id', Integer(), primary_key=True, autoincrement=False), + Column('id', Integer(), primary_key=True, autoincrement=True), + mysql_engine='InnoDB' + ) + + self.assert_compile( + schema.CreateTable(t1), + "CREATE TABLE sometable (" + "assigned_id INTEGER NOT NULL, " + "id INTEGER NOT NULL AUTO_INCREMENT, " + "PRIMARY KEY (assigned_id, id), " + "KEY `idx_autoinc_id`(`id`)" + ")ENGINE=InnoDB" + ) + + t1 = Table('sometable', MetaData(), + Column('assigned_id', Integer(), primary_key=True, autoincrement=True), + Column('id', Integer(), primary_key=True, autoincrement=False), + mysql_engine='InnoDB' + ) + + self.assert_compile( + schema.CreateTable(t1), + "CREATE TABLE sometable (" + "assigned_id INTEGER NOT NULL AUTO_INCREMENT, " + "id INTEGER NOT NULL, " + "PRIMARY KEY (assigned_id, id)" + ")ENGINE=InnoDB" + ) + class RawReflectionTest(TestBase): def setup(self):