mirror of
https://github.com/simonw/datasette.git
synced 2026-10-21 00:36:59 +02:00
Fix _shape=arrays and _shape=arrayfirst for rows containing infinity
remove_infinites() returns a plain list for sqlite3.Row rows that contain infinity, which caused a 500 error with these two shapes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GaqG8H8ajwxizKXdbGrtve
This commit is contained in:
parent
cf113a5985
commit
e8c7b469fa
2 changed files with 27 additions and 14 deletions
|
|
@ -6,7 +6,6 @@ from datasette.utils import (
|
|||
error_body,
|
||||
path_from_row_pks,
|
||||
remove_infinites,
|
||||
sqlite3,
|
||||
value_as_boolean,
|
||||
)
|
||||
from datasette.utils.asgi import Response
|
||||
|
|
@ -59,13 +58,11 @@ def json_renderer(request, args, data, error, truncated=None):
|
|||
if truncated is not None:
|
||||
data["truncated"] = truncated
|
||||
if shape == "arrayfirst":
|
||||
if not data["rows"]:
|
||||
data = []
|
||||
elif isinstance(data["rows"][0], sqlite3.Row):
|
||||
data = [row[0] for row in data["rows"]]
|
||||
else:
|
||||
assert isinstance(data["rows"][0], dict)
|
||||
data = [next(iter(row.values())) for row in data["rows"]]
|
||||
# Rows can be dicts, sqlite3.Row or lists (from remove_infinites)
|
||||
data = [
|
||||
next(iter(row.values())) if isinstance(row, dict) else row[0]
|
||||
for row in data["rows"]
|
||||
]
|
||||
elif shape in ("objects", "object", "array"):
|
||||
columns = data.get("columns")
|
||||
rows = data.get("rows")
|
||||
|
|
@ -94,12 +91,10 @@ def json_renderer(request, args, data, error, truncated=None):
|
|||
data = data["rows"]
|
||||
|
||||
elif shape == "arrays":
|
||||
if not data["rows"]:
|
||||
pass
|
||||
elif isinstance(data["rows"][0], sqlite3.Row):
|
||||
data["rows"] = [list(row) for row in data["rows"]]
|
||||
else:
|
||||
data["rows"] = [list(row.values()) for row in data["rows"]]
|
||||
data["rows"] = [
|
||||
list(row.values()) if isinstance(row, dict) else list(row)
|
||||
for row in data["rows"]
|
||||
]
|
||||
else:
|
||||
status_code = 400
|
||||
data = error_body(f"Invalid _shape: {shape}", status_code)
|
||||
|
|
|
|||
|
|
@ -1302,6 +1302,24 @@ async def test_infinity_returned_as_invalid_json_if_requested(ds_client):
|
|||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"shape,expected",
|
||||
(
|
||||
("arrays", {"ok": True, "rows": [[None], [None], [1.5]], "truncated": False}),
|
||||
("arrayfirst", [None, None, 1.5]),
|
||||
),
|
||||
)
|
||||
async def test_infinity_with_array_shapes(ds_client, shape, expected):
|
||||
# Rows containing infinity are lists rather than sqlite3.Row objects
|
||||
response = await ds_client.get(
|
||||
"/fixtures/-/query.json?sql=select+value+from+infinity+order+by+rowid"
|
||||
"&_shape=" + shape
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == expected
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_custom_query_with_unicode_characters(ds_client):
|
||||
# /fixtures/𝐜𝐢𝐭𝐢𝐞𝐬.json
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue