mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-24 10:54:12 +02:00
Initial tests for .create(..., transform=True), refs #467
This commit is contained in:
parent
5ef47d6c30
commit
1e7959d7a6
2 changed files with 79 additions and 8 deletions
|
|
@ -897,7 +897,8 @@ class Database:
|
||||||
# Transform table to match the new definition if table already exists:
|
# Transform table to match the new definition if table already exists:
|
||||||
if transform and self[name].exists():
|
if transform and self[name].exists():
|
||||||
table = cast(Table, self[name])
|
table = cast(Table, self[name])
|
||||||
# First add missing columns and columns to drop
|
needs_transform = False
|
||||||
|
# First add missing columns and figure out columns to drop
|
||||||
existing_columns = table.columns_dict
|
existing_columns = table.columns_dict
|
||||||
missing_columns = dict(
|
missing_columns = dict(
|
||||||
(col_name, col_type)
|
(col_name, col_type)
|
||||||
|
|
@ -910,13 +911,26 @@ class Database:
|
||||||
if missing_columns:
|
if missing_columns:
|
||||||
for col_name, col_type in missing_columns.items():
|
for col_name, col_type in missing_columns.items():
|
||||||
table.add_column(col_name, col_type)
|
table.add_column(col_name, col_type)
|
||||||
# Do we need to reset the column order?
|
if missing_columns or columns_to_drop:
|
||||||
column_order = None
|
needs_transform = True
|
||||||
if list(existing_columns) != list(columns):
|
# Do we need to change the column order?
|
||||||
column_order = list(columns)
|
if (
|
||||||
|
column_order
|
||||||
|
and list(existing_columns)[: len(column_order)] != column_order
|
||||||
|
):
|
||||||
|
needs_transform = True
|
||||||
|
# Has the primary key changed?
|
||||||
|
current_pks = table.pks
|
||||||
|
desired_pk = None
|
||||||
|
if isinstance(pk, str):
|
||||||
|
desired_pk = [pk]
|
||||||
|
elif pk:
|
||||||
|
desired_pk = list(pk)
|
||||||
|
if desired_pk and current_pks != desired_pk:
|
||||||
|
needs_transform = True
|
||||||
# Only run .transform() if there is something to do
|
# Only run .transform() if there is something to do
|
||||||
# TODO: this misses changes like pk= without also column changes
|
# TODO: what about not null and defaults?
|
||||||
if columns_to_drop or missing_columns or column_order:
|
if needs_transform:
|
||||||
table.transform(
|
table.transform(
|
||||||
types=columns,
|
types=columns,
|
||||||
drop=columns_to_drop,
|
drop=columns_to_drop,
|
||||||
|
|
@ -1692,7 +1706,9 @@ class Table(Queryable):
|
||||||
elif not not_null:
|
elif not not_null:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
assert False, "not_null must be a dict or a set or None, it was {}".format(repr(not_null))
|
assert False, "not_null must be a dict or a set or None, it was {}".format(
|
||||||
|
repr(not_null)
|
||||||
|
)
|
||||||
# defaults=
|
# defaults=
|
||||||
create_table_defaults = {
|
create_table_defaults = {
|
||||||
(rename.get(c.name) or c.name): c.default_value
|
(rename.get(c.name) or c.name): c.default_value
|
||||||
|
|
|
||||||
|
|
@ -1155,3 +1155,58 @@ def test_create_if_no_columns(fresh_db):
|
||||||
with pytest.raises(AssertionError) as error:
|
with pytest.raises(AssertionError) as error:
|
||||||
fresh_db["t"].create({})
|
fresh_db["t"].create({})
|
||||||
assert error.value.args[0] == "Tables must have at least one column"
|
assert error.value.args[0] == "Tables must have at least one column"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"cols,kwargs,expected_schema,should_transform",
|
||||||
|
(
|
||||||
|
# Change nothing
|
||||||
|
(
|
||||||
|
{"id": int, "name": str},
|
||||||
|
{"pk": "id"},
|
||||||
|
"CREATE TABLE [demo] (\n [id] INTEGER PRIMARY KEY,\n [name] TEXT\n)",
|
||||||
|
False,
|
||||||
|
),
|
||||||
|
# Drop name column, remove primary key
|
||||||
|
({"id": int}, {}, 'CREATE TABLE "demo" (\n [id] INTEGER\n)', True),
|
||||||
|
# Add a new column
|
||||||
|
(
|
||||||
|
{"id": int, "name": str, "age": int},
|
||||||
|
{"pk": "id"},
|
||||||
|
'CREATE TABLE "demo" (\n [id] INTEGER PRIMARY KEY,\n [name] TEXT,\n [age] INTEGER\n)',
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
# Change the primary key
|
||||||
|
(
|
||||||
|
{"id": int, "name": str},
|
||||||
|
{"pk": "name"},
|
||||||
|
'CREATE TABLE "demo" (\n [id] INTEGER,\n [name] TEXT PRIMARY KEY\n)',
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
# Change in column order
|
||||||
|
(
|
||||||
|
{"id": int, "name": str},
|
||||||
|
{"pk": "id", "column_order": ["name"]},
|
||||||
|
'CREATE TABLE "demo" (\n [name] TEXT,\n [id] INTEGER PRIMARY KEY\n)',
|
||||||
|
True,
|
||||||
|
),
|
||||||
|
# Same column order is ignored
|
||||||
|
(
|
||||||
|
{"id": int, "name": str},
|
||||||
|
{"pk": "id", "column_order": ["id", "name"]},
|
||||||
|
"CREATE TABLE [demo] (\n [id] INTEGER PRIMARY KEY,\n [name] TEXT\n)",
|
||||||
|
False,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
def test_create_transform(fresh_db, cols, kwargs, expected_schema, should_transform):
|
||||||
|
fresh_db.create_table("demo", {"id": int, "name": str}, pk="id")
|
||||||
|
fresh_db["demo"].insert({"id": 1, "name": "Cleo"})
|
||||||
|
traces = []
|
||||||
|
with fresh_db.tracer(lambda sql, parameters: traces.append((sql, parameters))):
|
||||||
|
fresh_db["demo"].create(cols, **kwargs, transform=True)
|
||||||
|
new_schema = fresh_db["demo"].schema
|
||||||
|
assert new_schema == expected_schema, repr(new_schema)
|
||||||
|
at_least_one_create_table = any(sql.startswith("CREATE TABLE") for sql, _ in traces)
|
||||||
|
assert should_transform == at_least_one_create_table
|
||||||
|
assert fresh_db["demo"].count == 1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue