mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-08 09:34:08 +02:00
Auto-decode columns declared as JSON in output modes (issue #579)
Columns declared with type JSON now decode automatically wherever nested
JSON is already supported (query/rows/search/memory output, and the
Python API), without needing --json-cols. Uses sqlite3's built-in
detect_types=PARSE_DECLTYPES + a registered JSON converter, so it works
transparently through joins and aliases. Flat formats (CSV/TSV/table/raw)
re-serialize decoded values back to JSON text instead of a Python repr.
Also adds "JSON" as a first-class column type for create()/add_column()/
transform(), and fixes column_affinity("JSON") so transform() doesn't
rewrite JSON columns as REAL.
This commit is contained in:
parent
c989cdf5a2
commit
f34dfb25da
8 changed files with 99 additions and 10 deletions
|
|
@ -170,6 +170,10 @@ def column_affinity(column_type: str) -> type:
|
|||
column_type = column_type.upper().strip()
|
||||
if column_type == "":
|
||||
return str # We differ from spec, which says it should be BLOB
|
||||
if "JSON" in column_type:
|
||||
# Not a real SQLite affinity, but sqlite-utils treats JSON as a
|
||||
# supported column type (see issue 579) and it is stored as text
|
||||
return str
|
||||
if "INT" in column_type:
|
||||
return int
|
||||
if "CHAR" in column_type or "CLOB" in column_type or "TEXT" in column_type:
|
||||
|
|
@ -182,6 +186,19 @@ def column_affinity(column_type: str) -> type:
|
|||
return float
|
||||
|
||||
|
||||
def _json_column_converter(raw: bytes) -> Any:
|
||||
# Registered as the sqlite3 converter for columns declared as JSON, see
|
||||
# https://github.com/simonw/sqlite-utils/issues/579 - falls back to the
|
||||
# decoded text unchanged if it does not turn out to be valid JSON
|
||||
try:
|
||||
return json.loads(raw)
|
||||
except ValueError:
|
||||
return raw.decode("utf-8", "replace")
|
||||
|
||||
|
||||
sqlite3.register_converter("JSON", _json_column_converter)
|
||||
|
||||
|
||||
def decode_base64_values(doc: dict[str, Any]) -> dict[str, Any]:
|
||||
# Looks for '{"$base64": true..., "encoded": ...}' values and decodes them
|
||||
to_fix = [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue