Add --update-incoming-fks CLI flag for transform command

When renaming columns that are referenced by foreign keys in other
tables, the --update-incoming-fks flag will automatically update
those FK constraints.

Example:
    sqlite-utils transform mydb.db authors \
        --rename id author_pk \
        --update-incoming-fks

This will rename the 'id' column to 'author_pk' and also update any
foreign key constraints in other tables (e.g., books.author_id)
that reference the renamed column.
This commit is contained in:
Claude 2026-01-21 14:58:11 +00:00
commit 798149b816
No known key found for this signature in database
2 changed files with 46 additions and 0 deletions

View file

@ -2545,6 +2545,11 @@ def schema(
multiple=True,
help="Drop foreign key constraint for this column",
)
@click.option(
"--update-incoming-fks",
is_flag=True,
help="Update foreign keys in other tables that reference renamed columns",
)
@click.option("--sql", is_flag=True, help="Output SQL without executing it")
@load_extension_option
def transform(
@ -2562,6 +2567,7 @@ def transform(
default_none,
add_foreign_keys,
drop_foreign_keys,
update_incoming_fks,
sql,
load_extension,
):
@ -2615,6 +2621,8 @@ def transform(
kwargs["drop_foreign_keys"] = drop_foreign_keys
if add_foreign_keys:
kwargs["add_foreign_keys"] = add_foreign_keys
if update_incoming_fks:
kwargs["update_incoming_fks"] = True
if sql:
for line in db.table(table).transform_sql(**kwargs):

View file

@ -1810,6 +1810,44 @@ def test_transform_add_or_drop_foreign_key(db_path, extra_args, expected_schema)
assert schema == expected_schema
def test_transform_update_incoming_fks_cli(db_path):
"""Test --update-incoming-fks flag updates foreign keys in other tables"""
db = Database(db_path)
with db.conn:
db["authors"].insert({"id": 1, "name": "Alice"}, pk="id")
db["books"].insert(
{"id": 1, "title": "Book A", "author_id": 1},
pk="id",
foreign_keys=[("author_id", "authors", "id")],
)
# Rename authors.id to authors.author_pk with --update-incoming-fks
result = CliRunner().invoke(
cli.cli,
[
"transform",
db_path,
"authors",
"--rename", "id", "author_pk",
"--update-incoming-fks",
],
)
assert result.exit_code == 0, result.output
# Verify authors column was renamed
assert "author_pk" in db["authors"].columns_dict
assert "id" not in db["authors"].columns_dict
# Verify books FK was updated
assert db["books"].schema == (
'CREATE TABLE "books" (\n'
' "id" INTEGER PRIMARY KEY,\n'
' "title" TEXT,\n'
' "author_id" INTEGER REFERENCES "authors"("author_pk")\n'
")"
)
_common_other_schema = (
'CREATE TABLE "species" (\n "id" INTEGER PRIMARY KEY,\n "species" TEXT\n)'
)