From: Mike Bayer Date: Sun, 12 Feb 2012 22:14:34 +0000 (-0500) Subject: - [bug] Fixed bug in new "autoload_replace" flag X-Git-Tag: rel_0_7_6~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=345de2ee1dfb12c6314144c2b7ed6fb4a7a3cb7c;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - [bug] Fixed bug in new "autoload_replace" flag which would fail to preserve the primary key constraint of the reflected table. [ticket:2402] --- diff --git a/CHANGES b/CHANGES index 79f6cd4681..a97a9c60db 100644 --- a/CHANGES +++ b/CHANGES @@ -42,6 +42,11 @@ CHANGES in a result set row using their original in-Python names. [ticket:2396] + - [bug] Fixed bug in new "autoload_replace" flag + which would fail to preserve the primary + key constraint of the reflected table. + [ticket:2402] + - engine - [feature] Added pool_reset_on_return argument to create_engine, allows control over diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index f5911f3b63..71d97e65f8 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -317,7 +317,7 @@ class Inspector(object): info_cache=self.info_cache, **kw) return indexes - def reflecttable(self, table, include_columns, exclude_columns=None): + def reflecttable(self, table, include_columns, exclude_columns=()): """Given a Table object, load its internal constructs based on introspection. This is the underlying method used by most dialects to produce @@ -414,9 +414,12 @@ class Inspector(object): # Primary keys pk_cons = self.get_pk_constraint(table_name, schema, **tblkw) if pk_cons: + pk_cols = [table.c[pk] + for pk in pk_cons['constrained_columns'] + if pk in table.c and pk not in exclude_columns + ] + [pk for pk in table.primary_key if pk.key in exclude_columns] primary_key_constraint = sa_schema.PrimaryKeyConstraint(name=pk_cons.get('name'), - *[table.c[pk] for pk in pk_cons['constrained_columns'] - if pk in table.c] + *pk_cols ) table.append_constraint(primary_key_constraint) diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index c183e43855..83a6e0f37d 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -369,9 +369,12 @@ class Table(SchemaItem, expression.TableClause): # allow user-overrides self._init_items(*args) - def _autoload(self, metadata, autoload_with, include_columns, exclude_columns=None): + def _autoload(self, metadata, autoload_with, include_columns, exclude_columns=()): if self.primary_key.columns: - PrimaryKeyConstraint()._set_parent_with_dispatch(self) + PrimaryKeyConstraint(*[ + c for c in self.primary_key.columns + if c.key in exclude_columns + ])._set_parent_with_dispatch(self) if autoload_with: autoload_with.run_callable( @@ -424,7 +427,7 @@ class Table(SchemaItem, expression.TableClause): if not autoload_replace: exclude_columns = [c.name for c in self.c] else: - exclude_columns = None + exclude_columns = () self._autoload(self.metadata, autoload_with, include_columns, exclude_columns) self._extra_kwargs(**kwargs) diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py index 13c8ee0ef0..f385a0fa23 100644 --- a/test/engine/test_reflection.py +++ b/test/engine/test_reflection.py @@ -203,7 +203,7 @@ class ReflectionTest(fixtures.TestBase, ComparesTables): assert len(t2.indexes) == 2 @testing.provide_metadata - def test_autoload_replace(self): + def test_autoload_replace_foreign_key(self): a = Table('a', self.metadata, Column('id', Integer, primary_key=True)) b = Table('b', self.metadata, Column('id', Integer, primary_key=True), Column('a_id', Integer)) @@ -220,6 +220,18 @@ class ReflectionTest(fixtures.TestBase, ComparesTables): assert b2.c.a_id.references(a2.c.id) eq_(len(b2.constraints), 2) + @testing.provide_metadata + def test_autoload_replace_primary_key(self): + a = Table('a', self.metadata, Column('id', Integer)) + self.metadata.create_all() + + m2 = MetaData() + a2 = Table('a', m2, Column('id', Integer, primary_key=True)) + + Table('a', m2, autoload=True, autoload_with=testing.db, + autoload_replace=False, extend_existing=True) + eq_(list(a2.primary_key), [a2.c.id]) + def test_autoload_replace_arg(self): Table('t', MetaData(), autoload_replace=False)