summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2016-06-03 15:07:14 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2016-06-03 15:07:14 -0400
commitdaf209bd6b6fe94cbec162cef2a53c49e9f31cde (patch)
tree3072a482649ef2130728235f7641fc51693c22dd
parenta6817579cee4fb2569d961b611a4190f3f9fb7ee (diff)
downloadsqlalchemy-daf209bd6b6fe94cbec162cef2a53c49e9f31cde.tar.gz
Ensure 'options' is always present in foreign key info
Regarding 0e88bcc30ed49193b91f248123f526fa30007f22, "options" needs to be present as a key in the dictionary because Alembic uses this as a guide to know if the backend is even capable of reporting on foreign key options. Change-Id: I271090f75088cfeec24315a878060f9b8a265335
-rw-r--r--lib/sqlalchemy/dialects/sqlite/base.py3
-rw-r--r--lib/sqlalchemy/testing/requirements.py4
-rw-r--r--lib/sqlalchemy/testing/suite/test_reflection.py51
-rw-r--r--test/requirements.py3
4 files changed, 59 insertions, 2 deletions
diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py
index 85ebaaa1d..7ddd09993 100644
--- a/lib/sqlalchemy/dialects/sqlite/base.py
+++ b/lib/sqlalchemy/dialects/sqlite/base.py
@@ -1420,8 +1420,7 @@ class SQLiteDialect(default.DefaultDialect):
continue
key = keys_by_signature.pop(sig)
key['name'] = constraint_name
- if options:
- key['options'] = options
+ key['options'] = options
fkeys.append(key)
# assume the remainders are the unnamed, inline constraints, just
# use them as is as it's extremely difficult to parse inline
diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py
index d4c0dff8f..a9370a30e 100644
--- a/lib/sqlalchemy/testing/requirements.py
+++ b/lib/sqlalchemy/testing/requirements.py
@@ -340,6 +340,10 @@ class SuiteRequirements(Requirements):
return exclusions.open()
@property
+ def foreign_key_constraint_option_reflection(self):
+ return exclusions.closed()
+
+ @property
def temp_table_reflection(self):
return exclusions.open()
diff --git a/lib/sqlalchemy/testing/suite/test_reflection.py b/lib/sqlalchemy/testing/suite/test_reflection.py
index 1874f6210..dced2e345 100644
--- a/lib/sqlalchemy/testing/suite/test_reflection.py
+++ b/lib/sqlalchemy/testing/suite/test_reflection.py
@@ -472,6 +472,57 @@ class ComponentReflectionTest(fixtures.TablesTest):
def test_get_foreign_keys_with_schema(self):
self._test_get_foreign_keys(schema=testing.config.test_schema)
+ @testing.requires.foreign_key_constraint_option_reflection
+ @testing.provide_metadata
+ def test_get_foreign_key_options(self):
+ meta = self.metadata
+
+ Table(
+ 'x', meta,
+ Column('id', Integer, primary_key=True),
+ )
+
+ Table('table', meta,
+ Column('id', Integer, primary_key=True),
+ Column('x_id', Integer, sa.ForeignKey('x.id', name='xid')),
+ Column('test', String(10)),
+ test_needs_fk=True)
+
+ Table('user', meta,
+ Column('id', Integer, primary_key=True),
+ Column('name', String(50), nullable=False),
+ Column('tid', Integer),
+ sa.ForeignKeyConstraint(
+ ['tid'], ['table.id'],
+ name='myfk',
+ onupdate="SET NULL", ondelete="CASCADE"),
+ test_needs_fk=True)
+
+ meta.create_all()
+
+ insp = inspect(meta.bind)
+
+ # test 'options' is always present for a backend
+ # that can reflect these, since alembic looks for this
+ opts = insp.get_foreign_keys('table')[0]['options']
+
+ eq_(
+ dict(
+ (k, opts[k])
+ for k in opts if opts[k]
+ ),
+ {}
+ )
+
+ opts = insp.get_foreign_keys('user')[0]['options']
+ eq_(
+ dict(
+ (k, opts[k])
+ for k in opts if opts[k]
+ ),
+ {'onupdate': 'SET NULL', 'ondelete': 'CASCADE'}
+ )
+
@testing.provide_metadata
def _test_get_indexes(self, schema=None):
meta = self.metadata
diff --git a/test/requirements.py b/test/requirements.py
index 0609b3cbf..554e5296f 100644
--- a/test/requirements.py
+++ b/test/requirements.py
@@ -84,6 +84,9 @@ class DefaultRequirements(SuiteRequirements):
return only_on(['oracle'])
+ @property
+ def foreign_key_constraint_option_reflection(self):
+ return only_on(['postgresql', 'mysql', 'sqlite'])
@property
def unbounded_varchar(self):