]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Ensure 'options' is always present in foreign key info
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 3 Jun 2016 19:07:14 +0000 (15:07 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 3 Jun 2016 19:07:14 +0000 (15:07 -0400)
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

lib/sqlalchemy/dialects/sqlite/base.py
lib/sqlalchemy/testing/requirements.py
lib/sqlalchemy/testing/suite/test_reflection.py
test/requirements.py

index 85ebaaa1d0ed8ddd989cea3b79c0ee3db9481652..7ddd0999353ba03cceddec7fc5969a5da75e5fb0 100644 (file)
@@ -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
index d4c0dff8fbd874f91c419aff6fe476f5b48887cf..a9370a30e27beff5424e8b1e18b31d8d4c16b62e 100644 (file)
@@ -339,6 +339,10 @@ class SuiteRequirements(Requirements):
     def foreign_key_constraint_reflection(self):
         return exclusions.open()
 
+    @property
+    def foreign_key_constraint_option_reflection(self):
+        return exclusions.closed()
+
     @property
     def temp_table_reflection(self):
         return exclusions.open()
index 1874f6210e4eda5e3ea1a5a1e9a0b20447156296..dced2e345745d5381350f4a349f6dfde7f5b7729 100644 (file)
@@ -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
index 0609b3cbf1867f08bfef022f8a40c27438c44710..554e5296fe45791596343995919b330f877c9b63 100644 (file)
@@ -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):