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.
Fixes: #5463
Change-Id: Ic3b1e0a0385fb9e727b0880e90815ea2814df313
(cherry picked from commit
cb52b934000047278dbb63d0cfffdb4eae1f669c)
--- /dev/null
+.. 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.
+
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
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,
)
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"},
],
)