From 1a03276d199b1af3f7a301cb84e488cbecc1ccce Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sun, 23 Sep 2012 12:51:24 -0400 Subject: [PATCH] - [bug] When the primary key column of a Table is replaced, such as via extend_existing, the "auto increment" column used by insert() constructs is reset. Previously it would remain referring to the previous primary key column. [ticket:2525] --- CHANGES | 6 ++++++ lib/sqlalchemy/schema.py | 4 ++-- lib/sqlalchemy/util/langhelpers.py | 2 ++ test/sql/test_metadata.py | 17 ++++++++++++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 590ac62a9d..ee5f368dd1 100644 --- a/CHANGES +++ b/CHANGES @@ -390,6 +390,12 @@ CHANGES returned by SQLite cursor.description. [ticket:2475] + - [bug] When the primary key column of a Table + is replaced, such as via extend_existing, + the "auto increment" column used by insert() + constructs is reset. Previously it would + remain referring to the previous primary + key column. [ticket:2525] 0.7.6 ===== diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 02f62b6746..b8c74c53cc 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -456,14 +456,13 @@ class Table(SchemaItem, expression.TableClause): def _init_collections(self): pass - @util.memoized_property def _autoincrement_column(self): for col in self.primary_key: if col.autoincrement and \ col.type._type_affinity is not None and \ issubclass(col.type._type_affinity, sqltypes.Integer) and \ - (not col.foreign_keys or col.autoincrement=='ignore_fk') and \ + (not col.foreign_keys or col.autoincrement == 'ignore_fk') and \ isinstance(col.default, (type(None), Sequence)) and \ (col.server_default is None or col.server_default.reflected): return col @@ -1029,6 +1028,7 @@ class Column(SchemaItem, expression.ColumnClause): if self.primary_key: table.primary_key._replace(self) + Table._autoincrement_column._reset(table) elif self.key in table.primary_key: raise exc.ArgumentError( "Trying to redefine primary-key column '%s' as a " diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 94fbd5eb8e..a33d4358e4 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -494,6 +494,8 @@ class memoized_property(object): obj.__dict__[self.__name__] = result = self.fget(obj) return result + def _reset(self, obj): + obj.__dict__.pop(self.__name__, None) class memoized_instancemethod(object): """Decorate a method memoize its return value. diff --git a/test/sql/test_metadata.py b/test/sql/test_metadata.py index 44daf554e1..7e77adf5c3 100644 --- a/test/sql/test_metadata.py +++ b/test/sql/test_metadata.py @@ -13,7 +13,7 @@ import sqlalchemy as tsa from test.lib import fixtures from test.lib import testing from test.lib.testing import ComparesTables, AssertsCompiledSQL -from test.lib.testing import eq_ +from test.lib.testing import eq_, is_ class MetaDataTest(fixtures.TestBase, ComparesTables): def test_metadata_connect(self): @@ -720,6 +720,21 @@ class TableTest(fixtures.TestBase, AssertsCompiledSQL): assign2 ) + def test_autoincrement_replace(self): + m = MetaData() + + t = Table('t', m, + Column('id', Integer, primary_key=True) + ) + + is_(t._autoincrement_column, t.c.id) + + t = Table('t', m, + Column('id', Integer, primary_key=True), + extend_existing=True + ) + is_(t._autoincrement_column, t.c.id) + class SchemaTest(fixtures.TestBase, AssertsCompiledSQL): def test_default_schema_metadata_fk(self): -- 2.47.2