From ab8d4aad0c42f905640981f6f24bc1e37205ae62 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Sat, 24 Jul 2021 15:08:36 -0700 Subject: [PATCH] sqlite-utils schema now takes optional tables, closes #299 --- docs/cli.rst | 5 ++++ sqlite_utils/cli.py | 10 ++++++-- tests/test_cli.py | 57 +++++++++++++++++++++++++++++++++------------ 3 files changed, 55 insertions(+), 17 deletions(-) diff --git a/docs/cli.rst b/docs/cli.rst index a404333..d8993e4 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -525,6 +525,11 @@ The ``sqlite-utils schema`` command shows the full SQL schema for the database:: [name] TEXT ); +This will show the schema for every table and index in the database. To view the schema just for a specified subset of tables pass those as additional arguments:: + + $ sqlite-utils schema dogs.db dogs chickens + ... + .. _cli_analyze_tables: Analyzing tables diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 8a4910f..b168ec0 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -1550,15 +1550,21 @@ def indexes( type=click.Path(file_okay=True, dir_okay=False, allow_dash=False), required=True, ) +@click.argument("tables", nargs=-1, required=False) @load_extension_option def schema( path, + tables, load_extension, ): - "Show full schema for this database" + "Show full schema for this database or for specified tables" db = sqlite_utils.Database(path) _load_extensions(db, load_extension) - click.echo(db.schema) + if tables: + for table in tables: + click.echo(db[table].schema) + else: + click.echo(db.schema) @cli.command() diff --git a/tests/test_cli.py b/tests/test_cli.py index 37a96a3..e84453a 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -2064,7 +2064,46 @@ def test_triggers(tmpdir, extra_args, expected): assert result.output == expected -def test_schema(tmpdir): +@pytest.mark.parametrize( + "options,expected", + ( + ( + [], + ( + "CREATE TABLE [dogs] (\n" + " [id] INTEGER,\n" + " [name] TEXT\n" + ");\n" + "CREATE TABLE [chickens] (\n" + " [id] INTEGER,\n" + " [name] TEXT,\n" + " [breed] TEXT\n" + ");\n" + "CREATE INDEX [idx_chickens_breed]\n" + " ON [chickens] ([breed]);\n" + ), + ), + ( + ["dogs"], + ("CREATE TABLE [dogs] (\n" " [id] INTEGER,\n" " [name] TEXT\n" ")\n"), + ), + ( + ["chickens", "dogs"], + ( + "CREATE TABLE [chickens] (\n" + " [id] INTEGER,\n" + " [name] TEXT,\n" + " [breed] TEXT\n" + ")\n" + "CREATE TABLE [dogs] (\n" + " [id] INTEGER,\n" + " [name] TEXT\n" + ")\n" + ), + ), + ), +) +def test_schema(tmpdir, options, expected): db_path = str(tmpdir / "test.db") db = Database(db_path) db["dogs"].create({"id": int, "name": str}) @@ -2072,23 +2111,11 @@ def test_schema(tmpdir): db["chickens"].create_index(["breed"]) result = CliRunner().invoke( cli.cli, - ["schema", db_path], + ["schema", db_path] + options, catch_exceptions=False, ) assert result.exit_code == 0 - assert result.output == ( - "CREATE TABLE [dogs] (\n" - " [id] INTEGER,\n" - " [name] TEXT\n" - ");\n" - "CREATE TABLE [chickens] (\n" - " [id] INTEGER,\n" - " [name] TEXT,\n" - " [breed] TEXT\n" - ");\n" - "CREATE INDEX [idx_chickens_breed]\n" - " ON [chickens] ([breed]);\n" - ) + assert result.output == expected def test_long_csv_column_value(tmpdir):