From: ijl Date: Sun, 13 Oct 2013 21:13:28 +0000 (-0400) Subject: #2183: Metadata.reflect() foreign keys include options when the dialect exposes it X-Git-Tag: rel_0_9_0b1~11^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=52cfa74e094c32910fa1076375f1ae0c9795d45d;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git #2183: Metadata.reflect() foreign keys include options when the dialect exposes it --- diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py index fd6a47a10c..f3da25a92d 100644 --- a/lib/sqlalchemy/dialects/mysql/base.py +++ b/lib/sqlalchemy/dialects/mysql/base.py @@ -2175,7 +2175,7 @@ class MySQLDialect(default.DefaultDialect): ref_names = spec['foreign'] con_kw = {} - for opt in ('name', 'onupdate', 'ondelete'): + for opt in ('onupdate', 'ondelete'): if spec.get(opt, False): con_kw[opt] = spec[opt] diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index a9ccf55397..461f5eb231 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -564,9 +564,14 @@ class Inspector(object): ) for column in referred_columns: refspec.append(".".join([referred_table, column])) + if 'options' in fkey_d: + options = fkey_d['options'] + else: + options = {} table.append_constraint( sa_schema.ForeignKeyConstraint(constrained_columns, refspec, - conname, link_to_name=True)) + conname, link_to_name=True, + **options)) # Indexes indexes = self.get_indexes(table_name, schema) for index_d in indexes: diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py index 92220b0d11..3f9ff00670 100644 --- a/lib/sqlalchemy/sql/schema.py +++ b/lib/sqlalchemy/sql/schema.py @@ -2396,7 +2396,9 @@ class ForeignKeyConstraint(Constraint): ondelete=self.ondelete, use_alter=self.use_alter, link_to_name=self.link_to_name, - match=self.match + match=self.match, + deferrable=self.deferrable, + initially=self.initially ) if table is not None: diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py index 21c0509156..3b23bf31aa 100644 --- a/test/engine/test_reflection.py +++ b/test/engine/test_reflection.py @@ -602,6 +602,47 @@ class ReflectionTest(fixtures.TestBase, ComparesTables): is a2.c.user_id assert u2.join(a2).onclause.compare(u2.c.id == a2.c.user_id) + @testing.only_on(['postgresql', 'mysql']) + @testing.provide_metadata + def test_fk_options(self): + """test that foreign key reflection includes options (on + backends with {dialect}.get_foreign_keys() support)""" + + # fk whose attributes we're testing on reflection + addresses_user_id_fkey = sa.ForeignKey( + 'users.id', + name = 'addresses_user_id_fkey', + match='FULL', + onupdate='RESTRICT', + ondelete='RESTRICT', + deferrable=True, + initially='DEFERRED' + ) + + # only test implemented attrs + if testing.against('postgresql'): + test_attrs = ('match', 'onupdate', 'ondelete', 'deferrable', 'initially') + elif testing.against('mysql'): + test_attrs = ('onupdate', 'ondelete') + + meta = self.metadata + Table('users', meta, + Column('id', sa.Integer, primary_key=True), + Column('name', sa.String(30)), + test_needs_fk=True) + Table('addresses', meta, + Column('id', sa.Integer, primary_key=True), + Column('user_id', sa.Integer, addresses_user_id_fkey), + test_needs_fk=True) + meta.create_all() + + meta2 = MetaData() + meta2.reflect(testing.db) + for fk in meta2.tables['addresses'].foreign_keys: + ref = locals()[fk.name] + for attr in test_attrs: + assert getattr(fk, attr) == getattr(ref, attr) + def test_pks_not_uniques(self): """test that primary key reflection not tripped up by unique indexes"""