summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorijl <uijllji@gmail.com>2013-10-13 17:13:28 -0400
committerijl <uijllji@gmail.com>2013-10-13 17:13:28 -0400
commit52cfa74e094c32910fa1076375f1ae0c9795d45d (patch)
treef3408fa65519d4f17b16421fc6c2a8038b4c4d47
parent9d952e0a11709fe35ada2635a79043ca0fc7ffbf (diff)
downloadsqlalchemy-52cfa74e094c32910fa1076375f1ae0c9795d45d.tar.gz
#2183: Metadata.reflect() foreign keys include options when the dialect exposes it
-rw-r--r--lib/sqlalchemy/dialects/mysql/base.py2
-rw-r--r--lib/sqlalchemy/engine/reflection.py7
-rw-r--r--lib/sqlalchemy/sql/schema.py4
-rw-r--r--test/engine/test_reflection.py41
4 files changed, 51 insertions, 3 deletions
diff --git a/lib/sqlalchemy/dialects/mysql/base.py b/lib/sqlalchemy/dialects/mysql/base.py
index fd6a47a10..f3da25a92 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 a9ccf5539..461f5eb23 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 92220b0d1..3f9ff0067 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 21c050915..3b23bf31a 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"""