diff options
| -rw-r--r-- | doc/build/changelog/unreleased_14/5463.rst | 8 | ||||
| -rw-r--r-- | lib/sqlalchemy/dialects/sqlite/base.py | 12 | ||||
| -rw-r--r-- | lib/sqlalchemy/testing/suite/test_reflection.py | 6 |
3 files changed, 20 insertions, 6 deletions
diff --git a/doc/build/changelog/unreleased_14/5463.rst b/doc/build/changelog/unreleased_14/5463.rst new file mode 100644 index 000000000..5de6182ac --- /dev/null +++ b/doc/build/changelog/unreleased_14/5463.rst @@ -0,0 +1,8 @@ +.. change:: + :tags: bug, sqlite, reflection + :tickets: 5463 + + Fixed bug where the name of CHECK constraints under SQLite would not be + reflected if the name were created using quotes, as is the case when the + name uses mixed case or special characters. + diff --git a/lib/sqlalchemy/dialects/sqlite/base.py b/lib/sqlalchemy/dialects/sqlite/base.py index 03f35d5e2..b1ac20383 100644 --- a/lib/sqlalchemy/dialects/sqlite/base.py +++ b/lib/sqlalchemy/dialects/sqlite/base.py @@ -2430,17 +2430,21 @@ class SQLiteDialect(default.DefaultDialect): if not table_data: return [] - CHECK_PATTERN = r"(?:CONSTRAINT (\w+) +)?" r"CHECK *\( *(.+) *\),? *" + CHECK_PATTERN = r"(?:CONSTRAINT (.+) +)?" r"CHECK *\( *(.+) *\),? *" check_constraints = [] # NOTE: we aren't using re.S here because we actually are # taking advantage of each CHECK constraint being all on one # line in the table definition in order to delineate. This # necessarily makes assumptions as to how the CREATE TABLE # was emitted. + for match in re.finditer(CHECK_PATTERN, table_data, re.I): - check_constraints.append( - {"sqltext": match.group(2), "name": match.group(1)} - ) + name = match.group(1) + + if name: + name = re.sub(r'^"|"$', "", name) + + check_constraints.append({"sqltext": match.group(2), "name": name}) return check_constraints diff --git a/lib/sqlalchemy/testing/suite/test_reflection.py b/lib/sqlalchemy/testing/suite/test_reflection.py index fb12d23c8..278f89472 100644 --- a/lib/sqlalchemy/testing/suite/test_reflection.py +++ b/lib/sqlalchemy/testing/suite/test_reflection.py @@ -1178,7 +1178,9 @@ class ComponentReflectionTestExtra(fixtures.TestBase): metadata, Column("a", Integer()), sa.CheckConstraint("a > 1 AND a < 5", name="cc1"), - sa.CheckConstraint("a = 1 OR (a > 2 AND a < 5)", name="cc2"), + sa.CheckConstraint( + "a = 1 OR (a > 2 AND a < 5)", name="UsesCasing" + ), schema=schema, ) @@ -1205,8 +1207,8 @@ class ComponentReflectionTestExtra(fixtures.TestBase): eq_( reflected, [ + {"name": "UsesCasing", "sqltext": "a = 1 or a > 2 and a < 5"}, {"name": "cc1", "sqltext": "a > 1 and a < 5"}, - {"name": "cc2", "sqltext": "a = 1 or a > 2 and a < 5"}, ], ) |
