Added 'sqlite-utils rows db.db tablename' command

This commit is contained in:
Simon Willison 2019-02-22 17:52:17 -08:00
commit c7dbb03a10
3 changed files with 69 additions and 8 deletions

View file

@ -13,10 +13,14 @@ Running queries and returning JSON
You can execute a SQL query against a database and get the results back as JSON like this::
$ sqlite-utils dogs.db "select * from dogs"
$ sqlite-utils query dogs.db "select * from dogs"
[{"id": 1, "age": 4, "name": "Cleo"},
{"id": 2, "age": 2, "name": "Pancakes"}]
This is the default subcommand for ``sqlite-utils``, so you can instead use this::
$ sqlite-utils dogs.db "select * from dogs"
Use ``--nl`` to get back newline-delimited JSON objects::
$ sqlite-utils dogs.db "select * from dogs" --nl
@ -69,6 +73,19 @@ This will default to including the column names as a header row. To exclude the
1,4,Cleo
2,2,Pancakes
.. _cli_rows:
Returning all rows in a table
=============================
You can return every row in a specified table using the ``rows`` subcommand::
$ sqlite-utils rows dogs.db dogs
[{"id": 1, "age": 4, "name": "Cleo"},
{"id": 2, "age": 2, "name": "Pancakes"}]
This command accepts the same output options as ``query`` - so you can pass ``--nl``, ``--csv`` and ``--no-headers``.
Listing tables
==============

View file

@ -208,13 +208,6 @@ def upsert(path, table, json_file, pk, nl, csv, batch_size):
)
@click.argument("sql")
@output_options
@click.option("--nl", help="Output newline-delimited JSON", is_flag=True, default=False)
@click.option(
"--arrays",
help="Output rows as arrays instead of objects",
is_flag=True,
default=False,
)
def query(path, sql, nl, arrays, csv, no_headers):
"Execute SQL query and return the results as JSON"
db = sqlite_utils.Database(path)
@ -231,6 +224,28 @@ def query(path, sql, nl, arrays, csv, no_headers):
click.echo(line)
@cli.command()
@click.argument(
"path",
type=click.Path(file_okay=True, dir_okay=False, allow_dash=False),
required=True,
)
@click.argument("table")
@output_options
@click.pass_context
def rows(ctx, path, table, nl, arrays, csv, no_headers):
"Output all rows in the specified table"
ctx.invoke(
query,
path=path,
sql="select * from [{}]".format(table),
nl=nl,
arrays=arrays,
csv=csv,
no_headers=no_headers,
)
def output_rows(iterator, headers, nl, arrays):
# We have to iterate two-at-a-time so we can know if we
# should output a trailing comma or if we have reached

View file

@ -236,3 +236,32 @@ def test_query_json(db_path, sql, args, expected):
)
result = CliRunner().invoke(cli.cli, [db_path, sql] + args)
assert expected == result.output.strip()
@pytest.mark.parametrize(
"args,expected",
[
(
[],
'[{"id": 1, "name": "Cleo", "age": 4},\n {"id": 2, "name": "Pancakes", "age": 2}]',
),
(
["--nl"],
'{"id": 1, "name": "Cleo", "age": 4}\n{"id": 2, "name": "Pancakes", "age": 2}',
),
(["--arrays"], '[[1, "Cleo", 4],\n [2, "Pancakes", 2]]'),
(["--arrays", "--nl"], '[1, "Cleo", 4]\n[2, "Pancakes", 2]'),
],
)
def test_rows(db_path, args, expected):
db = Database(db_path)
with db.conn:
db["dogs"].insert_all(
[
{"id": 1, "age": 4, "name": "Cleo"},
{"id": 2, "age": 2, "name": "Pancakes"},
],
column_order=("id", "name", "age"),
)
result = CliRunner().invoke(cli.cli, ["rows", db_path, "dogs"] + args)
assert expected == result.output.strip()