.transform(strict=) and sqlite-utils transform --strict/--no-strict (#788)

* .transform(strict=) and sqlite-utils transform --strict/--no-strict

Closes #787
This commit is contained in:
Simon Willison 2026-07-11 16:43:37 -07:00 committed by GitHub
commit b74b727035
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 171 additions and 8 deletions

View file

@ -2718,6 +2718,11 @@ def schema(
multiple=True,
help="Drop foreign key constraint for this column",
)
@click.option(
"--strict/--no-strict",
default=None,
help="Enable or disable STRICT mode (default: preserve current mode)",
)
@click.option("--sql", is_flag=True, help="Output SQL without executing it")
@load_extension_option
def transform(
@ -2735,6 +2740,7 @@ def transform(
default_none,
add_foreign_keys,
drop_foreign_keys,
strict,
sql,
load_extension,
):
@ -2796,6 +2802,7 @@ def transform(
defaults=default_dict,
drop_foreign_keys=drop_foreign_keys_value,
add_foreign_keys=add_foreign_keys_value,
strict=strict,
):
click.echo(line)
else:
@ -2809,6 +2816,7 @@ def transform(
defaults=default_dict,
drop_foreign_keys=drop_foreign_keys_value,
add_foreign_keys=add_foreign_keys_value,
strict=strict,
)

View file

@ -2514,6 +2514,7 @@ class Table(Queryable):
foreign_keys: Optional[ForeignKeysType] = None,
column_order: Optional[List[str]] = None,
keep_table: Optional[str] = None,
strict: Optional[bool] = None,
) -> "Table":
"""
Apply an advanced alter table, including operations that are not supported by
@ -2536,6 +2537,8 @@ class Table(Queryable):
to use when creating the table
:param keep_table: If specified, the existing table will be renamed to this and will not be
dropped
:param strict: Set to ``True`` to make the table strict or ``False`` to make it
non-strict. Defaults to ``None``, which preserves the existing strict mode.
"""
if not self.exists():
raise ValueError("Cannot transform a table that doesn't exist yet")
@ -2551,6 +2554,7 @@ class Table(Queryable):
foreign_keys=foreign_keys,
column_order=column_order,
keep_table=keep_table,
strict=strict,
)
pragma_foreign_keys_was_on = bool(
self.db.execute("PRAGMA foreign_keys").fetchone()[0]
@ -2587,6 +2591,8 @@ class Table(Queryable):
self.db.execute("PRAGMA defer_foreign_keys=OFF;")
if should_disable_foreign_keys:
self.db.execute("PRAGMA foreign_keys=1;")
if strict is not None:
self._defaults["strict"] = strict
return self
def transform_sql(
@ -2604,6 +2610,7 @@ class Table(Queryable):
column_order: Optional[List[str]] = None,
tmp_suffix: Optional[str] = None,
keep_table: Optional[str] = None,
strict: Optional[bool] = None,
) -> List[str]:
"""
Return a list of SQL statements that should be executed in order to apply this transformation.
@ -2624,7 +2631,11 @@ class Table(Queryable):
:param tmp_suffix: Suffix to use for the temporary table name
:param keep_table: If specified, the existing table will be renamed to this and will not be
dropped
:param strict: Set to ``True`` to make the table strict or ``False`` to make it
non-strict. Defaults to ``None``, which preserves the existing strict mode.
"""
if strict is True and not self.db.supports_strict:
raise TransformError("SQLite does not support STRICT tables")
types = types or {}
rename = rename or {}
drop = drop or set()
@ -2806,7 +2817,7 @@ class Table(Queryable):
defaults=create_table_defaults,
foreign_keys=create_table_foreign_keys,
column_order=column_order,
strict=self.strict,
strict=self.strict if strict is None else strict,
).strip()
)