This commit is contained in:
ChrisJr404 2026-09-02 03:57:12 -07:00 committed by GitHub
commit cf84fcd631
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 109 additions and 3 deletions

View file

@ -711,7 +711,7 @@ See :ref:`cli_tables`.
::
Usage: sqlite-utils tables [OPTIONS] PATH
Usage: sqlite-utils tables [OPTIONS] PATH [NAMES]...
List the tables in the database
@ -719,6 +719,10 @@ See :ref:`cli_tables`.
sqlite-utils tables trees.db
Pass one or more table names to restrict the output to just those tables:
sqlite-utils tables trees.db plants seeds
Options:
--fts4 Just show FTS4 enabled tables
--fts5 Just show FTS5 enabled tables
@ -756,7 +760,7 @@ See :ref:`cli_views`.
::
Usage: sqlite-utils views [OPTIONS] PATH
Usage: sqlite-utils views [OPTIONS] PATH [NAMES]...
List the views in the database
@ -764,6 +768,10 @@ See :ref:`cli_views`.
sqlite-utils views trees.db
Pass one or more view names to restrict the output to just those views:
sqlite-utils views trees.db recent_plants
Options:
--counts Include row counts per view
--nl Output newline-delimited JSON

View file

@ -747,6 +747,19 @@ You can list the names of tables in a database using the ``tables`` command:
{"table": "cats"},
{"table": "chickens"}]
Pass one or more table names to restrict the output to just those tables. This is useful with ``--counts`` against a database that has a large table you want to skip:
.. code-block:: bash
sqlite-utils tables mydb.db dogs cats --counts
.. code-block:: output
[{"table": "dogs", "count": 12},
{"table": "cats", "count": 332}]
The tables are listed in the order you name them. An error is raised, and a non-zero exit code returned, if any of the named tables do not exist.
You can output this list in CSV using the ``--csv`` or ``--tsv`` options:
.. code-block:: bash
@ -843,6 +856,8 @@ It takes the same options as the ``tables`` command:
* ``--tsv``
* ``--table``
As with ``tables``, you can pass one or more view names to restrict the output to just those views.
.. note::
In Python: :ref:`db.views or db.view_names() <python_api_views>` CLI reference: :ref:`sqlite-utils views <cli_ref_views>`

View file

@ -187,6 +187,7 @@ def cli():
type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False),
required=True,
)
@click.argument("names", nargs=-1)
@click.option(
"--fts4", help="Just show FTS4 enabled tables", default=False, is_flag=True
)
@ -212,6 +213,7 @@ def cli():
@load_extension_option
def tables(
path,
names,
fts4,
fts5,
counts,
@ -235,6 +237,11 @@ def tables(
\b
sqlite-utils tables trees.db
Pass one or more table names to restrict the output to just those tables:
\b
sqlite-utils tables trees.db plants seeds
"""
db = sqlite_utils.Database(path)
_register_db_for_cleanup(db)
@ -249,8 +256,25 @@ def tables(
method = db.view if views else db.table
if names:
existing = set(db.view_names() if views else db.table_names())
missing = [name for name in names if name not in existing]
if missing:
label = "view" if views else "table"
if len(missing) == 1:
message = "The following {} does not exist: {}".format(
label, missing[0]
)
else:
message = "The following {}s do not exist: {}".format(
label, ", ".join(missing)
)
raise click.ClickException(message)
def _iter():
if views:
if names:
items = list(names)
elif views:
items = db.view_names()
else:
items = db.table_names(fts4=fts4, fts5=fts5)
@ -293,6 +317,7 @@ def tables(
type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False),
required=True,
)
@click.argument("names", nargs=-1)
@click.option(
"--counts", help="Include row counts per view", default=False, is_flag=True
)
@ -312,6 +337,7 @@ def tables(
@load_extension_option
def views(
path,
names,
counts,
nl,
arrays,
@ -332,10 +358,16 @@ def views(
\b
sqlite-utils views trees.db
Pass one or more view names to restrict the output to just those views:
\b
sqlite-utils views trees.db recent_plants
"""
assert tables.callback is not None
tables.callback(
path=path,
names=names,
fts4=False,
fts5=False,
counts=counts,

View file

@ -140,6 +140,57 @@ def test_tables_schema(db_path):
) == result.output.strip()
def test_tables_specific_names(db_path):
result = CliRunner().invoke(
cli.cli, ["tables", db_path, "Gosh2"], catch_exceptions=False
)
assert '[{"table": "Gosh2"}]' == result.output.strip()
def test_tables_specific_names_preserve_argument_order(db_path):
result = CliRunner().invoke(
cli.cli, ["tables", db_path, "Gosh2", "Gosh"], catch_exceptions=False
)
assert '[{"table": "Gosh2"},\n {"table": "Gosh"}]' == result.output.strip()
def test_tables_specific_names_with_counts(db_path):
result = CliRunner().invoke(
cli.cli, ["tables", db_path, "Gosh", "--counts"], catch_exceptions=False
)
assert '[{"table": "Gosh", "count": 0}]' == result.output.strip()
def test_tables_missing_name_errors(db_path):
result = CliRunner().invoke(cli.cli, ["tables", db_path, "Gosh", "nope"])
assert result.exit_code == 1
assert "The following table does not exist: nope" in result.output
def test_tables_multiple_missing_names_errors(db_path):
result = CliRunner().invoke(cli.cli, ["tables", db_path, "nope", "nope2"])
assert result.exit_code == 1
assert "The following tables do not exist: nope, nope2" in result.output
def test_views_specific_names(db_path):
db = Database(db_path)
db.create_view("v1", "select 1")
db.create_view("v2", "select 2")
result = CliRunner().invoke(
cli.cli, ["views", db_path, "v2"], catch_exceptions=False
)
assert '[{"view": "v2"}]' == result.output.strip()
def test_views_missing_name_errors(db_path):
db = Database(db_path)
db.create_view("v1", "select 1")
result = CliRunner().invoke(cli.cli, ["views", db_path, "nope"])
assert result.exit_code == 1
assert "The following view does not exist: nope" in result.output
@pytest.mark.parametrize(
"options,expected",
[