mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-28 12:54:15 +02:00
Merge 81e2ad8a44 into 85b1be10c8
This commit is contained in:
commit
cf84fcd631
4 changed files with 109 additions and 3 deletions
|
|
@ -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
|
List the tables in the database
|
||||||
|
|
||||||
|
|
@ -719,6 +719,10 @@ See :ref:`cli_tables`.
|
||||||
|
|
||||||
sqlite-utils tables trees.db
|
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:
|
Options:
|
||||||
--fts4 Just show FTS4 enabled tables
|
--fts4 Just show FTS4 enabled tables
|
||||||
--fts5 Just show FTS5 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
|
List the views in the database
|
||||||
|
|
||||||
|
|
@ -764,6 +768,10 @@ See :ref:`cli_views`.
|
||||||
|
|
||||||
sqlite-utils views trees.db
|
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:
|
Options:
|
||||||
--counts Include row counts per view
|
--counts Include row counts per view
|
||||||
--nl Output newline-delimited JSON
|
--nl Output newline-delimited JSON
|
||||||
|
|
|
||||||
15
docs/cli.rst
15
docs/cli.rst
|
|
@ -747,6 +747,19 @@ You can list the names of tables in a database using the ``tables`` command:
|
||||||
{"table": "cats"},
|
{"table": "cats"},
|
||||||
{"table": "chickens"}]
|
{"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:
|
You can output this list in CSV using the ``--csv`` or ``--tsv`` options:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
@ -843,6 +856,8 @@ It takes the same options as the ``tables`` command:
|
||||||
* ``--tsv``
|
* ``--tsv``
|
||||||
* ``--table``
|
* ``--table``
|
||||||
|
|
||||||
|
As with ``tables``, you can pass one or more view names to restrict the output to just those views.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
In Python: :ref:`db.views or db.view_names() <python_api_views>` CLI reference: :ref:`sqlite-utils views <cli_ref_views>`
|
In Python: :ref:`db.views or db.view_names() <python_api_views>` CLI reference: :ref:`sqlite-utils views <cli_ref_views>`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -187,6 +187,7 @@ def cli():
|
||||||
type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False),
|
type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
|
@click.argument("names", nargs=-1)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--fts4", help="Just show FTS4 enabled tables", default=False, is_flag=True
|
"--fts4", help="Just show FTS4 enabled tables", default=False, is_flag=True
|
||||||
)
|
)
|
||||||
|
|
@ -212,6 +213,7 @@ def cli():
|
||||||
@load_extension_option
|
@load_extension_option
|
||||||
def tables(
|
def tables(
|
||||||
path,
|
path,
|
||||||
|
names,
|
||||||
fts4,
|
fts4,
|
||||||
fts5,
|
fts5,
|
||||||
counts,
|
counts,
|
||||||
|
|
@ -235,6 +237,11 @@ def tables(
|
||||||
|
|
||||||
\b
|
\b
|
||||||
sqlite-utils tables trees.db
|
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)
|
db = sqlite_utils.Database(path)
|
||||||
_register_db_for_cleanup(db)
|
_register_db_for_cleanup(db)
|
||||||
|
|
@ -249,8 +256,25 @@ def tables(
|
||||||
|
|
||||||
method = db.view if views else db.table
|
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():
|
def _iter():
|
||||||
if views:
|
if names:
|
||||||
|
items = list(names)
|
||||||
|
elif views:
|
||||||
items = db.view_names()
|
items = db.view_names()
|
||||||
else:
|
else:
|
||||||
items = db.table_names(fts4=fts4, fts5=fts5)
|
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),
|
type=click.Path(exists=True, file_okay=True, dir_okay=False, allow_dash=False),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
|
@click.argument("names", nargs=-1)
|
||||||
@click.option(
|
@click.option(
|
||||||
"--counts", help="Include row counts per view", default=False, is_flag=True
|
"--counts", help="Include row counts per view", default=False, is_flag=True
|
||||||
)
|
)
|
||||||
|
|
@ -312,6 +337,7 @@ def tables(
|
||||||
@load_extension_option
|
@load_extension_option
|
||||||
def views(
|
def views(
|
||||||
path,
|
path,
|
||||||
|
names,
|
||||||
counts,
|
counts,
|
||||||
nl,
|
nl,
|
||||||
arrays,
|
arrays,
|
||||||
|
|
@ -332,10 +358,16 @@ def views(
|
||||||
|
|
||||||
\b
|
\b
|
||||||
sqlite-utils views trees.db
|
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
|
assert tables.callback is not None
|
||||||
tables.callback(
|
tables.callback(
|
||||||
path=path,
|
path=path,
|
||||||
|
names=names,
|
||||||
fts4=False,
|
fts4=False,
|
||||||
fts5=False,
|
fts5=False,
|
||||||
counts=counts,
|
counts=counts,
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,57 @@ def test_tables_schema(db_path):
|
||||||
) == result.output.strip()
|
) == 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(
|
@pytest.mark.parametrize(
|
||||||
"options,expected",
|
"options,expected",
|
||||||
[
|
[
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue