Skip to content

Commit

Permalink
Enhance FK reflection with Unicode names (#225)
Browse files Browse the repository at this point in the history
Accommodate differences in quoting between CockroachDB
and PostgreSQL

Also bump cryptography version as per #223
  • Loading branch information
gordthompson committed Oct 3, 2023
1 parent ab64f6d commit b6005ff
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Unreleased

- Implement reflection for array types (#213)
- Fix get_multi_columns() to support multiple table names in filter_array (#220)
- Enhance foreign key reflection to accommodate quoting differences with PostgreSQL

# Version 2.0.1
April 14, 2023
Expand Down
2 changes: 1 addition & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cffi==1.15.1
# via cryptography
charset-normalizer==3.2.0
# via requests
cryptography==41.0.3
cryptography==41.0.4
# via secretstorage
distlib==0.3.7
# via virtualenv
Expand Down
30 changes: 20 additions & 10 deletions sqlalchemy_cockroachdb/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import re
import threading
from sqlalchemy import text
from sqlalchemy import util
from sqlalchemy.dialects.postgresql.base import PGDialect
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.dialects.postgresql import INET
Expand Down Expand Up @@ -357,6 +358,24 @@ def get_foreign_keys_v1(self, conn, table_name, schema=None, **kw):
fkeys.append(fkey_d)
return fkeys

@util.memoized_property
def _fk_regex_pattern(self):
# optionally quoted token
qtoken = r'(?:"[^"]+"|[\w]+?)'

# https://www.postgresql.org/docs/current/static/sql-createtable.html
return re.compile(
r"FOREIGN KEY \((.*?)\) "
rf"REFERENCES (?:({qtoken})\.)?({qtoken})\(((?:{qtoken}(?: *, *)?)+)\)" # noqa: E501
r"[\s]?(MATCH (FULL|PARTIAL|SIMPLE)+)?"
r"[\s]?(ON UPDATE "
r"(CASCADE|RESTRICT|NO ACTION|SET NULL|SET DEFAULT)+)?"
r"[\s]?(ON DELETE "
r"(CASCADE|RESTRICT|NO ACTION|SET NULL|SET DEFAULT)+)?"
r"[\s]?(DEFERRABLE|NOT DEFERRABLE)?"
r"[\s]?(INITIALLY (DEFERRED|IMMEDIATE)+)?"
)

def get_foreign_keys(
self, connection, table_name, schema=None, postgresql_ignore_search_path=False, **kw
):
Expand Down Expand Up @@ -390,16 +409,7 @@ def get_foreign_keys(
ORDER BY 1
"""
# http://www.postgresql.org/docs/9.0/static/sql-createtable.html
FK_REGEX = re.compile(
r"FOREIGN KEY \((.*?)\) REFERENCES (?:(.*?)\.)?(.*?)[\s]?\((.*?)\)"
r"[\s]?(MATCH (FULL|PARTIAL|SIMPLE)+)?"
r"[\s]?(ON UPDATE "
r"(CASCADE|RESTRICT|NO ACTION|SET NULL|SET DEFAULT)+)?"
r"[\s]?(ON DELETE "
r"(CASCADE|RESTRICT|NO ACTION|SET NULL|SET DEFAULT)+)?"
r"[\s]?(DEFERRABLE|NOT DEFERRABLE)?"
r"[\s]?(INITIALLY (DEFERRED|IMMEDIATE)+)?"
)
FK_REGEX = self._fk_regex_pattern

t = sql.text(FK_SQL).columns(conname=sqltypes.Unicode, condef=sqltypes.Unicode)
c = connection.execute(t, {"table": table_oid})
Expand Down

0 comments on commit b6005ff

Please sign in to comment.