JSON output no longer escapes non-ASCII characters, new --ascii option

sqlite-utils query/rows/search/tables/views/triggers/indexes/memory now
output JSON with ensure_ascii=False, so unicode text like 日本語 is emitted
directly instead of as \uXXXX escape sequences. This matches how values
were already stored on insert (jsonify_if_needed) and how CSV/TSV output
already behaved.

A new --ascii flag on all of those commands restores the previous escaped
output, for systems that cannot handle UTF-8.

Also applies ensure_ascii=False to the convert --multi --dry-run preview
(matching what would actually be stored) and to plugins listing output.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JaHan1NhaTRAxJ9LQtSLf9
This commit is contained in:
Claude 2026-07-06 18:02:36 +00:00
commit 684dd2bf2b
No known key found for this signature in database
5 changed files with 114 additions and 6 deletions

View file

@ -1047,6 +1047,34 @@ def test_query_json_with_json_cols(db_path):
assert expected == result_rows.output.strip()
def test_query_json_unicode_not_escaped_by_default(db_path):
db = Database(db_path)
with db.conn:
db["text"].insert({"id": 1, "text": "Japanese 日本語"}, pk="id")
result = CliRunner().invoke(cli.cli, [db_path, "select id, text from text"])
assert result.exit_code == 0
assert result.output.strip() == '[{"id": 1, "text": "Japanese 日本語"}]'
# Same for --nl
result = CliRunner().invoke(cli.cli, [db_path, "select id, text from text", "--nl"])
assert result.exit_code == 0
assert result.output.strip() == '{"id": 1, "text": "Japanese 日本語"}'
@pytest.mark.parametrize("command", ["query", "rows"])
def test_query_json_ascii_option(db_path, command):
db = Database(db_path)
with db.conn:
db["text"].insert({"id": 1, "text": "Japanese 日本語"}, pk="id")
if command == "query":
args = [db_path, "select id, text from text", "--ascii"]
else:
args = ["rows", db_path, "text", "--ascii"]
result = CliRunner().invoke(cli.cli, args)
assert result.exit_code == 0
expected = '[{"id": 1, "text": "Japanese ' + "\\u65e5\\u672c\\u8a9e" + '"}]'
assert result.output.strip() == expected
@pytest.mark.parametrize(
"content,is_binary",
[(b"\x00\x0fbinary", True), ("this is text", False), (1, False), (1.5, False)],