diff --git a/docs/cli-reference.rst b/docs/cli-reference.rst index f03348f..6d6f837 100644 --- a/docs/cli-reference.rst +++ b/docs/cli-reference.rst @@ -1031,6 +1031,7 @@ See :ref:`cli_add_column`. --fk-col TEXT Referenced column on that foreign key table - if omitted will automatically use the primary key --not-null-default TEXT Add NOT NULL DEFAULT 'TEXT' constraint + --ignore If column already exists, do nothing --load-extension TEXT SQLite extensions to load -h, --help Show this message and exit. diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 999658d..de223af 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -418,9 +418,22 @@ def dump(path, load_extension): required=False, help="Add NOT NULL DEFAULT 'TEXT' constraint", ) +@click.option( + "--ignore", + is_flag=True, + help="If column already exists, do nothing", +) @load_extension_option def add_column( - path, table, col_name, col_type, fk, fk_col, not_null_default, load_extension + path, + table, + col_name, + col_type, + fk, + fk_col, + not_null_default, + ignore, + load_extension, ): """Add a column to the specified table @@ -431,9 +444,13 @@ def add_column( """ db = sqlite_utils.Database(path) _load_extensions(db, load_extension) - db[table].add_column( - col_name, col_type, fk=fk, fk_col=fk_col, not_null_default=not_null_default - ) + try: + db[table].add_column( + col_name, col_type, fk=fk, fk_col=fk_col, not_null_default=not_null_default + ) + except OperationalError as ex: + if not ignore: + raise click.ClickException(str(ex)) @cli.command(name="add-foreign-key") diff --git a/tests/test_cli.py b/tests/test_cli.py index e98ffc1..3694fd7 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -271,6 +271,19 @@ def test_add_column(db_path, col_name, col_type, expected_schema): assert expected_schema == collapse_whitespace(db["dogs"].schema) +@pytest.mark.parametrize("ignore", (True, False)) +def test_add_column_ignore(db_path, ignore): + db = Database(db_path) + db.create_table("dogs", {"name": str}) + args = ["add-column", db_path, "dogs", "name"] + (["--ignore"] if ignore else []) + result = CliRunner().invoke(cli.cli, args) + if ignore: + assert result.exit_code == 0 + else: + assert result.exit_code == 1 + assert result.output == "Error: duplicate column name: name\n" + + def test_add_column_not_null_default(db_path): db = Database(db_path) db.create_table("dogs", {"name": str})