mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-07-30 22:14:22 +02:00
Fix .transform() raising TransformError on column-level UNIQUE constraints
SQLite backs a column-level UNIQUE constraint with an auto-index whose sql in sqlite_master is NULL. The index-rebuild step in transform_sql() treated any NULL-sql index as an error, causing TransformError on tables with UNIQUE columns. The fix adds a 'unique' parameter to create_table_sql so the constraint is reproduced as an inline UNIQUE column attribute in the new CREATE TABLE statement. In transform_sql(), auto-UNIQUE indices (origin='u') are collected before the CREATE TABLE call and passed via unique=; the index rebuild loop then skips them with a continue instead of raising. Column renames are applied to the constraint; dropping a UNIQUE column drops its constraint silently. Fixes #762
This commit is contained in:
parent
7a52214624
commit
4d6d51ad02
2 changed files with 37 additions and 12 deletions
|
|
@ -681,15 +681,20 @@ def test_transform_with_unique_constraint_implicit_index(fresh_db):
|
|||
""")
|
||||
dogs.insert({"id": 1, "name": "Cleo", "age": 5})
|
||||
|
||||
# Attempt to transform the table without modifying 'name'
|
||||
with pytest.raises(TransformError) as excinfo:
|
||||
dogs.transform(types={"age": str})
|
||||
# Transform should succeed and preserve the UNIQUE constraint
|
||||
dogs.transform(types={"age": str})
|
||||
assert "UNIQUE" in dogs.schema
|
||||
|
||||
assert (
|
||||
"Index 'sqlite_autoindex_dogs_1' on table 'dogs' does not have a CREATE INDEX statement."
|
||||
in str(excinfo.value)
|
||||
)
|
||||
assert (
|
||||
"You must manually drop this index prior to running this transformation and manually recreate the new index after running this transformation."
|
||||
in str(excinfo.value)
|
||||
)
|
||||
# Duplicate name insert should still be rejected
|
||||
import pytest as _pytest
|
||||
with _pytest.raises(Exception):
|
||||
fresh_db.execute("INSERT INTO dogs VALUES (2, 'Cleo', '6')")
|
||||
|
||||
# Rename the UNIQUE column: constraint follows the new name
|
||||
dogs.transform(rename={"name": "dog_name"})
|
||||
assert "UNIQUE" in dogs.schema
|
||||
assert [c.name for c in dogs.columns] == ["id", "dog_name", "age"]
|
||||
|
||||
# Drop the UNIQUE column: transform completes without error
|
||||
dogs.transform(drop={"dog_name"})
|
||||
assert "dog_name" not in [c.name for c in dogs.columns]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue