diff --git a/docs/cli.rst b/docs/cli.rst index 119e49d..f75f370 100644 --- a/docs/cli.rst +++ b/docs/cli.rst @@ -55,6 +55,11 @@ If you want to pretty-print the output further, you can pipe it through ``python } ] +If you execute an `UPDATE` or `INSERT` query the comand will return the number of affected rows:: + + $ sqlite-utils dogs.db "update dogs set age = 5 where name = 'Cleo'" + [{"rows_affected": 1}] + You can run queries against a temporary in-memory database by passing ``:memory:`` as the filename:: $ sqlite-utils :memory: "select sqlite_version()" diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 4cbb13e..fe5cd64 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -669,14 +669,19 @@ def drop_view(path, view): def query(path, sql, nl, arrays, csv, no_headers, table, fmt, json_cols): "Execute SQL query and return the results as JSON" db = sqlite_utils.Database(path) - cursor = iter(db.conn.execute(sql)) - headers = [c[0] for c in cursor.description] + cursor = db.conn.execute(sql) + if cursor.description is None: + # This was an update/insert + headers = ["rows_affected"] + cursor = [[cursor.rowcount]] + else: + headers = [c[0] for c in cursor.description] if table: print(tabulate.tabulate(list(cursor), headers=headers, tablefmt=fmt)) elif csv: writer = csv_std.writer(sys.stdout) if not no_headers: - writer.writerow([c[0] for c in cursor.description]) + writer.writerow(headers) for row in cursor: writer.writerow(row) else: diff --git a/tests/test_cli.py b/tests/test_cli.py index 9cd5965..9e43fb9 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -1107,3 +1107,22 @@ def test_drop_view_error(): result = runner.invoke(cli.cli, ["drop-view", "test.db", "t2",],) assert 1 == result.exit_code assert 'Error: View "t2" does not exist' == result.output.strip() + + +@pytest.mark.parametrize( + "args,expected", + [ + ([], '[{"rows_affected": 1}]',), + (["-t"], "rows_affected\n---------------\n 1"), + ], +) +def test_query_update(db_path, args, expected): + db = Database(db_path) + with db.conn: + db["dogs"].insert_all( + [{"id": 1, "age": 4, "name": "Cleo"},] + ) + result = CliRunner().invoke( + cli.cli, [db_path, "update dogs set age = 5 where name = 'Cleo'"] + args + ) + assert expected == result.output.strip()