--- /dev/null
+.. change::
+ :tags: bug, sqlite
+ :tickets: 11746
+
+ Improvements to the regex used by the SQLite dialect to reflect the name
+ and contents of a UNIQUE constraint that is defined inline within a column
+ definition inside of a SQLite CREATE TABLE statement, accommodating for tab
+ characters present within the column / constraint line. Pull request
+ courtesy John A Stevenson.
+
+
+
return
UNIQUE_PATTERN = r'(?:CONSTRAINT "?(.+?)"? +)?UNIQUE *\((.+?)\)'
INLINE_UNIQUE_PATTERN = (
- r'(?:(".+?")|(?:[\[`])?([a-z0-9_]+)(?:[\]`])?) '
- r"+[a-z0-9_ ]+? +UNIQUE"
+ r'(?:(".+?")|(?:[\[`])?([a-z0-9_]+)(?:[\]`])?)[\t ]'
+ r"+[a-z0-9_ ]+?[\t ]+UNIQUE"
)
for match in re.finditer(UNIQUE_PATTERN, table_data, re.I):
argnames="colname,expected",
)
@testing.combinations(
- "uq", "uq_inline", "pk", "ix", argnames="constraint_type"
+ "uq",
+ "uq_inline",
+ "uq_inline_tab_before", # tab before column params
+ "uq_inline_tab_within", # tab within column params
+ "pk",
+ "ix",
+ argnames="constraint_type",
)
def test_constraint_cols(
self, colname, expected, constraint_type, connection, metadata
):
- if constraint_type == "uq_inline":
+ if constraint_type.startswith("uq_inline"):
+ inline_create_sql = {
+ "uq_inline": "CREATE TABLE t (%s INTEGER UNIQUE)",
+ "uq_inline_tab_before": "CREATE TABLE t (%s\tINTEGER UNIQUE)",
+ "uq_inline_tab_within": "CREATE TABLE t (%s INTEGER\tUNIQUE)",
+ }
+
t = Table("t", metadata, Column(colname, Integer))
connection.exec_driver_sql(
- """
- CREATE TABLE t (%s INTEGER UNIQUE)
- """
+ inline_create_sql[constraint_type]
% connection.dialect.identifier_preparer.quote(colname)
)
else:
t.create(connection)
- if constraint_type in ("uq", "uq_inline"):
+ if constraint_type in (
+ "uq",
+ "uq_inline",
+ "uq_inline_tab_before",
+ "uq_inline_tab_within",
+ ):
const = inspect(connection).get_unique_constraints("t")[0]
eq_(const["column_names"], [expected])
elif constraint_type == "pk":