mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-07-23 09:24:31 +02:00
--tsv output option, closes #193
This commit is contained in:
parent
771bd81b62
commit
afee15f04b
3 changed files with 65 additions and 28 deletions
20
docs/cli.rst
20
docs/cli.rst
|
|
@ -122,14 +122,14 @@ You can use the ``--json-cols`` option to automatically detect these JSON column
|
|||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]-
|
||||
|
||||
.. _cli_query_csv:
|
||||
|
||||
Running queries and returning CSV
|
||||
=================================
|
||||
|
||||
You can use the ``--csv`` option (or ``-c`` shortcut) to return results as CSV::
|
||||
You can use the ``--csv`` option to return results as CSV::
|
||||
|
||||
$ sqlite-utils dogs.db "select * from dogs" --csv
|
||||
id,age,name
|
||||
|
|
@ -142,6 +142,13 @@ This will default to including the column names as a header row. To exclude the
|
|||
1,4,Cleo
|
||||
2,2,Pancakes
|
||||
|
||||
Use ``--tsv`` instead of ``--csv`` to get back tab-separated values::
|
||||
|
||||
$ sqlite-utils dogs.db "select * from dogs" --tsv
|
||||
id age name
|
||||
1 4 Cleo
|
||||
2 2 Pancakes
|
||||
|
||||
.. _cli_query_table:
|
||||
|
||||
Running queries and outputting a table
|
||||
|
|
@ -189,7 +196,7 @@ You can return every row in a specified table using the ``rows`` command::
|
|||
[{"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``, ``--no-headers``, ``--table`` and ``--fmt``.
|
||||
This command accepts the same output options as ``query`` - so you can pass ``--nl``, ``--csv``, ``--tsv``, ``--no-headers``, ``--table`` and ``--fmt``.
|
||||
|
||||
.. _cli_tables:
|
||||
|
||||
|
|
@ -203,7 +210,7 @@ You can list the names of tables in a database using the ``tables`` command::
|
|||
{"table": "cats"},
|
||||
{"table": "chickens"}]
|
||||
|
||||
You can output this list in CSV using the ``--csv`` option::
|
||||
You can output this list in CSV using the ``--csv`` or ``--tsv`` options::
|
||||
|
||||
$ sqlite-utils tables mydb.db --csv --no-headers
|
||||
dogs
|
||||
|
|
@ -241,7 +248,7 @@ Use ``--schema`` to include the schema of each table::
|
|||
[age] INTEGER,
|
||||
[name] TEXT)
|
||||
|
||||
The ``--nl``, ``--csv`` and ``--table`` options are all available.
|
||||
The ``--nl``, ``--csv``, ``--tsv`` and ``--table`` options are all available.
|
||||
|
||||
.. _cli_views:
|
||||
|
||||
|
|
@ -263,6 +270,7 @@ It takes the same options as the ``tables`` command:
|
|||
* ``--counts``
|
||||
* ``--nl``
|
||||
* ``--csv``
|
||||
* ``--tsv``
|
||||
* ``--table``
|
||||
|
||||
.. _cli_inserting_data:
|
||||
|
|
@ -894,7 +902,7 @@ Once you have configured full-text search for a table, you can search it using `
|
|||
|
||||
$ sqlite-utils search mydb.db documents searchterm
|
||||
|
||||
This command accepts the same output options as ``sqlite-utils query``: ``--table``, ``--csv``, ``--nl`` etc.
|
||||
This command accepts the same output options as ``sqlite-utils query``: ``--table``, ``--csv``, ``--tsv``, ``--nl`` etc.
|
||||
|
||||
By default it shows the most relevant matches first. You can specify a different sort order using the ``-o`` option, which can take a column or a column followed by ``desc``::
|
||||
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ def output_options(fn):
|
|||
default=False,
|
||||
),
|
||||
click.option("--csv", is_flag=True, help="Output CSV"),
|
||||
click.option("--tsv", is_flag=True, help="Output TSV"),
|
||||
click.option("--no-headers", is_flag=True, help="Omit CSV headers"),
|
||||
click.option("-t", "--table", is_flag=True, help="Output as a table"),
|
||||
click.option(
|
||||
|
|
@ -120,6 +121,7 @@ def tables(
|
|||
nl,
|
||||
arrays,
|
||||
csv,
|
||||
tsv,
|
||||
no_headers,
|
||||
table,
|
||||
fmt,
|
||||
|
|
@ -161,8 +163,8 @@ def tables(
|
|||
|
||||
if table:
|
||||
print(tabulate.tabulate(_iter(), headers=headers, tablefmt=fmt))
|
||||
elif csv:
|
||||
writer = csv_std.writer(sys.stdout)
|
||||
elif csv or tsv:
|
||||
writer = csv_std.writer(sys.stdout, dialect="excel-tab" if tsv else "excel")
|
||||
if not no_headers:
|
||||
writer.writerow(headers)
|
||||
for row in _iter():
|
||||
|
|
@ -201,6 +203,7 @@ def views(
|
|||
nl,
|
||||
arrays,
|
||||
csv,
|
||||
tsv,
|
||||
no_headers,
|
||||
table,
|
||||
fmt,
|
||||
|
|
@ -218,6 +221,7 @@ def views(
|
|||
nl=nl,
|
||||
arrays=arrays,
|
||||
csv=csv,
|
||||
tsv=tsv,
|
||||
no_headers=no_headers,
|
||||
table=table,
|
||||
fmt=fmt,
|
||||
|
|
@ -930,6 +934,7 @@ def query(
|
|||
nl,
|
||||
arrays,
|
||||
csv,
|
||||
tsv,
|
||||
no_headers,
|
||||
table,
|
||||
fmt,
|
||||
|
|
@ -958,8 +963,8 @@ def query(
|
|||
sys.stdout.write(str(data))
|
||||
elif table:
|
||||
print(tabulate.tabulate(list(cursor), headers=headers, tablefmt=fmt))
|
||||
elif csv:
|
||||
writer = csv_std.writer(sys.stdout)
|
||||
elif csv or tsv:
|
||||
writer = csv_std.writer(sys.stdout, dialect="excel-tab" if tsv else "excel")
|
||||
if not no_headers:
|
||||
writer.writerow(headers)
|
||||
for row in cursor:
|
||||
|
|
@ -1003,6 +1008,7 @@ def search(
|
|||
nl,
|
||||
arrays,
|
||||
csv,
|
||||
tsv,
|
||||
no_headers,
|
||||
table,
|
||||
fmt,
|
||||
|
|
@ -1039,6 +1045,7 @@ def search(
|
|||
nl=nl,
|
||||
arrays=arrays,
|
||||
csv=csv,
|
||||
tsv=tsv,
|
||||
no_headers=no_headers,
|
||||
table=table,
|
||||
fmt=fmt,
|
||||
|
|
@ -1065,6 +1072,7 @@ def rows(
|
|||
nl,
|
||||
arrays,
|
||||
csv,
|
||||
tsv,
|
||||
no_headers,
|
||||
table,
|
||||
fmt,
|
||||
|
|
@ -1079,6 +1087,7 @@ def rows(
|
|||
nl=nl,
|
||||
arrays=arrays,
|
||||
csv=csv,
|
||||
tsv=tsv,
|
||||
no_headers=no_headers,
|
||||
table=table,
|
||||
fmt=fmt,
|
||||
|
|
|
|||
|
|
@ -62,24 +62,37 @@ def test_tables_counts_and_columns(db_path):
|
|||
) == result.output.strip()
|
||||
|
||||
|
||||
def test_tables_counts_and_columns_csv(db_path):
|
||||
@pytest.mark.parametrize(
|
||||
"format,expected",
|
||||
[
|
||||
(
|
||||
"--csv",
|
||||
(
|
||||
"table,count,columns\n"
|
||||
'Gosh,0,"c1\n'
|
||||
"c2\n"
|
||||
'c3"\n'
|
||||
'Gosh2,0,"c1\n'
|
||||
"c2\n"
|
||||
'c3"\n'
|
||||
'lots,30,"id\n'
|
||||
'age"'
|
||||
),
|
||||
),
|
||||
(
|
||||
"--tsv",
|
||||
"table\tcount\tcolumns\nGosh\t0\t['c1', 'c2', 'c3']\nGosh2\t0\t['c1', 'c2', 'c3']\nlots\t30\t['id', 'age']",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_tables_counts_and_columns_csv(db_path, format, expected):
|
||||
db = Database(db_path)
|
||||
with db.conn:
|
||||
db["lots"].insert_all([{"id": i, "age": i + 1} for i in range(30)])
|
||||
result = CliRunner().invoke(
|
||||
cli.cli, ["tables", "--counts", "--columns", "--csv", db_path]
|
||||
cli.cli, ["tables", "--counts", "--columns", format, db_path]
|
||||
)
|
||||
assert (
|
||||
"table,count,columns\n"
|
||||
'Gosh,0,"c1\n'
|
||||
"c2\n"
|
||||
'c3"\n'
|
||||
'Gosh2,0,"c1\n'
|
||||
"c2\n"
|
||||
'c3"\n'
|
||||
'lots,30,"id\n'
|
||||
'age"'
|
||||
) == result.output.strip()
|
||||
assert result.output.strip() == expected
|
||||
|
||||
|
||||
def test_tables_schema(db_path):
|
||||
|
|
@ -809,7 +822,14 @@ def test_insert_alter(db_path, tmpdir):
|
|||
] == db.execute_returning_dicts("select foo, n, baz from from_json_nl")
|
||||
|
||||
|
||||
def test_query_csv(db_path):
|
||||
@pytest.mark.parametrize(
|
||||
"format,expected",
|
||||
[
|
||||
("--csv", "id,name,age\n1,Cleo,4\n2,Pancakes,2\n"),
|
||||
("--tsv", "id\tname\tage\n1\tCleo\t4\n2\tPancakes\t2\n"),
|
||||
],
|
||||
)
|
||||
def test_query_csv(db_path, format, expected):
|
||||
db = Database(db_path)
|
||||
with db.conn:
|
||||
db["dogs"].insert_all(
|
||||
|
|
@ -819,15 +839,15 @@ def test_query_csv(db_path):
|
|||
]
|
||||
)
|
||||
result = CliRunner().invoke(
|
||||
cli.cli, [db_path, "select id, name, age from dogs", "--csv"]
|
||||
cli.cli, [db_path, "select id, name, age from dogs", format]
|
||||
)
|
||||
assert 0 == result.exit_code
|
||||
assert "id,name,age\n1,Cleo,4\n2,Pancakes,2\n" == result.output
|
||||
assert result.output == expected
|
||||
# Test the no-headers option:
|
||||
result = CliRunner().invoke(
|
||||
cli.cli, [db_path, "select id, name, age from dogs", "--no-headers", "--csv"]
|
||||
cli.cli, [db_path, "select id, name, age from dogs", "--no-headers", format]
|
||||
)
|
||||
assert "1,Cleo,4\n2,Pancakes,2\n" == result.output
|
||||
assert result.output.strip() == "\n".join(expected.split("\n")[1:]).strip()
|
||||
|
||||
|
||||
_all_query = "select id, name, age from dogs"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue