diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-08-18 13:03:49 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-08-18 16:34:48 -0400 |
| commit | f06c6ba67303e5c75d8ad044494193d8f97b2e2e (patch) | |
| tree | fdbc44d40171a12dc64ae65ad85dab728e900350 /lib/sqlalchemy/dialects/sqlite | |
| parent | 2051fa2ce9e724e6e77e19067d27d2660e7cd74a (diff) | |
| download | sqlalchemy-f06c6ba67303e5c75d8ad044494193d8f97b2e2e.tar.gz | |
Reflect PK of referred table if referred columns not present
Fixed bug where a FOREIGN KEY that was set up to refer to the parent table
by table name only without the column names would not correctly be
reflected as far as setting up the "referred columns", since SQLite's
PRAGMA does not report on these columns if they weren't given explicitly.
For some reason this was harcoded to assume the name of the local column,
which might work for some cases but is not correct. The new approach
reflects the primary key of the referred table and uses the constraint
columns list as the referred columns list, if the remote column(s) aren't
present in the reflected pragma directly.
Fixes: #4810
Change-Id: I7789f83d68845ae197a782080af8ec64a7bf48cc
Diffstat (limited to 'lib/sqlalchemy/dialects/sqlite')
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 78ce18ac6..7be0e06dc 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -1754,8 +1754,22 @@ class SQLiteDialect(default.DefaultDialect): for row in pragma_fks: (numerical_id, rtbl, lcol, rcol) = (row[0], row[2], row[3], row[4]) - if rcol is None: - rcol = lcol + if not rcol: + # no referred column, which means it was not named in the + # original DDL. The referred columns of the foreign key + # constraint are therefore the primary key of the referred + # table. + referred_pk = self.get_pk_constraint( + connection, rtbl, schema=schema, **kw + ) + # note that if table doesnt exist, we still get back a record, + # just it has no columns in it + referred_columns = referred_pk["constrained_columns"] + else: + # note we use this list only if this is the first column + # in the constraint. for subsequent columns we ignore the + # list and append "rcol" if present. + referred_columns = [] if self._broken_fk_pragma_quotes: rtbl = re.sub(r"^[\"\[`\']|[\"\]`\']$", "", rtbl) @@ -1768,13 +1782,15 @@ class SQLiteDialect(default.DefaultDialect): "constrained_columns": [], "referred_schema": schema, "referred_table": rtbl, - "referred_columns": [], + "referred_columns": referred_columns, "options": {}, } fks[numerical_id] = fk fk["constrained_columns"].append(lcol) - fk["referred_columns"].append(rcol) + + if rcol: + fk["referred_columns"].append(rcol) def fk_sig(constrained_columns, referred_table, referred_columns): return ( |
