mirror of
https://github.com/simonw/datasette.git
synced 2026-10-21 16:57:03 +02:00
Keep JSON parameter types for stored write queries and execute-write, refs #2946
Stored write queries converted every JSON value with str(), so null was
stored as 'None', true as 'True' and lists as Python repr. execute-write
kept JSON types but rejected arrays and objects and silently bound
missing parameters as empty strings.
Both endpoints now share one function for JSON parameters:
- strings, numbers and null pass through, true/false become 1/0, and
arrays and objects are stored as JSON text, matching the insert API
- missing parameters return a 400 listing them
- unknown parameters return a 400
Stored write queries keep their top-level body shape, with _json and
csrftoken as the only reserved keys. Parameters declared in "params"
are accepted, magic parameters are not required, and a body wrapped in
{"params": ...} gets an error explaining the difference.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012CXYAsBaNidHVk4GipkDjs
This commit is contained in:
parent
cf113a5985
commit
fecbed82b4
6 changed files with 281 additions and 16 deletions
|
|
@ -1705,6 +1705,10 @@ The request body must include a ``"sql"`` string. Named SQL parameters can be pr
|
|||
}
|
||||
}
|
||||
|
||||
Every named parameter in the SQL must have a value in ``"params"``, and ``"params"`` cannot contain keys that are not used by the SQL. Either mistake results in a ``400`` error such as ``"Missing parameters: name"`` or ``"Unknown parameters: breed"``.
|
||||
|
||||
Parameter values keep their JSON types, using the same rules as the :ref:`insert API <TableInsertView>`: strings, numbers and ``null`` are passed through unchanged, ``true`` and ``false`` become ``1`` and ``0``, and arrays and objects are passed as JSON text.
|
||||
|
||||
The SQL must be writable. Read-only ``select`` queries should use the regular :ref:`custom SQL query JSON API <json_api_custom_sql>` instead.
|
||||
|
||||
Datasette analyzes the SQL before executing it. The actor must have ``execute-write-sql`` permission for the database, and must also have any permissions required by the operations in the SQL. For example, inserts and updates against a table require ``insert-row``, ``update-row`` and ``delete-row`` permissions for that table. Reads performed as part of the write, such as ``insert into dogs select ... from other_table``, require ``view-table`` permission on the source table. Schema changes require ``create-table``, ``alter-table`` or ``drop-table`` permissions as appropriate.
|
||||
|
|
|
|||
|
|
@ -642,9 +642,22 @@ Writable queries can also be accessed using a JSON API. You can POST data to the
|
|||
To submit JSON to a writable query, encode key/value parameters as a JSON document::
|
||||
|
||||
POST /mydatabase/add_message
|
||||
Content-Type: application/json
|
||||
|
||||
{"message": "Message goes here"}
|
||||
|
||||
Each top-level key is the name of a parameter in the query's SQL, or one of the parameters listed in its ``"params"`` configuration. Parameters are not wrapped in a ``"params"`` object - that format is used by :ref:`execute-write <ExecuteWriteView>`, which needs to send the SQL as well.
|
||||
|
||||
The keys ``_json`` and ``csrftoken`` are reserved: they are never passed to the SQL query, so a query cannot use them as parameter names.
|
||||
|
||||
JSON values are passed to SQLite with their types intact, using the same rules as the :ref:`insert API <TableInsertView>`:
|
||||
|
||||
- Strings, numbers and ``null`` are passed through unchanged.
|
||||
- ``true`` and ``false`` are passed as ``1`` and ``0``.
|
||||
- Arrays and objects are passed as JSON text, so they can be used with SQLite functions such as ``json_each()``.
|
||||
|
||||
Every parameter used by the SQL must be included, apart from :ref:`magic parameters <queries_magic_parameters>`. Missing parameters or unknown keys result in a ``400`` error, for example ``"Missing parameters: message"``.
|
||||
|
||||
You can also continue to submit data using regular form encoding, like so::
|
||||
|
||||
POST /mydatabase/add_message
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue