diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 14aa338..a6ad7ca 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -9,6 +9,8 @@ import csv as csv_std import tabulate from .utils import sqlite3 +VALID_COLUMN_TYPES = ("INTEGER", "TEXT", "FLOAT", "BLOB") + def output_options(fn): for decorator in reversed( @@ -528,6 +530,35 @@ def upsert( ) +@cli.command(name="create-table") +@click.argument( + "path", + type=click.Path(file_okay=True, dir_okay=False, allow_dash=False), + required=True, +) +@click.argument("table") +@click.argument("columns", nargs=-1, required=True) +@click.option("--pk", help="Column to use as primary key") +def create_table(path, table, columns, pk): + "Add an index to the specified table covering the specified columns" + db = sqlite_utils.Database(path) + if len(columns) % 2 == 1: + raise click.ClickException( + "columns must be an even number of 'name' 'type' pairs" + ) + coltypes = {} + columns = list(columns) + while columns: + name = columns.pop(0) + ctype = columns.pop(0) + if ctype.upper() not in VALID_COLUMN_TYPES: + raise click.ClickException( + "column types must be one of {}".format(VALID_COLUMN_TYPES) + ) + coltypes[name] = ctype.upper() + db[table].create(coltypes, pk=pk) + + @cli.command() @click.argument( "path", diff --git a/tests/test_cli.py b/tests/test_cli.py index fe6bbb2..d002ac2 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -861,3 +861,39 @@ def test_upsert_alter(db_path, tmpdir): assert [{"id": 1, "name": "Cleo", "age": 5},] == db.execute_returning_dicts( "select * from dogs order by id" ) + + +def test_create_table(): + runner = CliRunner() + with runner.isolated_filesystem(): + result = runner.invoke( + cli.cli, + [ + "create-table", + "test.db", + "t", + "id", + "integer", + "name", + "text", + "age", + "integer", + "weight", + "float", + "thumbnail", + "blob", + "--pk", + "id", + ], + ) + assert 0 == result.exit_code + db = Database("test.db") + assert ( + "CREATE TABLE [t] (\n" + " [id] INTEGER PRIMARY KEY,\n" + " [name] TEXT,\n" + " [age] INTEGER,\n" + " [weight] FLOAT,\n" + " [thumbnail] BLOB\n" + ")" + ) == db["t"].schema