Docs for datasette methods for queries

Refs https://github.com/simonw/datasette/pull/2741#issuecomment-4549824373
This commit is contained in:
Simon Willison 2026-05-26 16:33:36 -07:00
commit 90e19a7d58
2 changed files with 199 additions and 5 deletions

View file

@ -29,7 +29,7 @@ Plugin API changes
~~~~~~~~~~~~~~~~~~
- The ``top_canned_query()`` plugin hook has been renamed to :ref:`top_stored_query() <plugin_hook_top_stored_query>`. (:issue:`2747`)
- The ``canned_queries()`` plugin hook has been removed. Plugins can use the new stored query methods together with :ref:`startup() <plugin_hook_startup>` to register queries. (:issue:`2735`)
- The ``canned_queries()`` plugin hook has been removed. Plugins can use the new :ref:`stored query management methods <datasette_stored_queries>` together with :ref:`startup() <plugin_hook_startup>` to register queries. (:issue:`2735`)
Bug fixes
~~~~~~~~~

View file

@ -927,6 +927,200 @@ Adds a new metadata entry for the specified column.
Any previous column-level metadata entry with the same ``key`` will be overwritten.
Internally upserts the value into the the ``metadata_columns`` table inside the :ref:`internal database <internals_internal>`.
.. _datasette_stored_queries:
Stored queries
--------------
:ref:`Stored queries <stored_queries>` are stored in the ``queries`` table in the :ref:`internal database <internals_internal>`. Plugins can use the following methods to add, update, list and remove stored queries.
.. _datasette_add_query:
await .add_query(database, name, sql, ...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Adds a stored query.
.. code-block:: python
async def add_query(
self,
database,
name,
sql,
*,
title=None,
description=None,
description_html=None,
hide_sql=False,
fragment=None,
parameters=None,
is_write=False,
is_private=False,
is_trusted=False,
source="plugin",
owner_id=None,
on_success_message=None,
on_success_message_sql=None,
on_success_redirect=None,
on_error_message=None,
on_error_redirect=None,
replace=True,
): ...
``database`` - string
The name of the database this query should belong to.
``name`` - string
The name of the stored query, used in the URL for that query.
``sql`` - string
The SQL for the stored query.
``title`` - string, optional
A display title for the query.
``description`` - string, optional
A plain text description.
``description_html`` - string, optional
An HTML description.
``hide_sql`` - boolean, optional
Set to ``True`` to hide the SQL by default on the query page.
``fragment`` - string, optional
A URL fragment to append to query links, for example ``"chart"``.
``parameters`` - list of strings, optional
Explicit parameter names for the query form. If omitted, Datasette derives parameters from the SQL.
``is_write`` - boolean, optional
Set to ``True`` for writable queries. They will the run against the SQLite write connection for the database.
``is_private`` - boolean, optional
Set to ``True`` for private queries. Private queries can only be viewed, updated or deleted by their owner.
``is_trusted`` - boolean, optional
Set to ``True`` for :ref:`trusted stored queries <trusted_stored_queries>`.
``source`` - string, optional
Identifies where the query came from. Defaults to ``"plugin"``.
``owner_id`` - string, optional
Actor ID of the query owner, used by private query permissions.
``on_success_message``, ``on_success_message_sql``, ``on_success_redirect``, ``on_error_message``, ``on_error_redirect`` - strings, optional
Options for :ref:`writable queries <queries_writable>`.
``replace`` - boolean, optional
Defaults to ``True``, which replaces any existing stored query with the same ``database`` and ``name``. Set this to ``False`` to raise a SQLite integrity error if the query already exists.
Example:
.. code-block:: python
await datasette.add_query(
database="fixtures",
name="recent_rows",
sql="select * from facetable order by created desc limit 10",
title="Recent rows",
source="my-plugin",
)
.. _datasette_update_query:
await .update_query(database, name, ...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Updates fields for an existing stored query. Only keyword arguments that are provided will be changed.
The available keyword arguments are the same as those for :ref:`datasette_add_query`, except for ``replace``. Pass ``None`` to clear optional text fields and options such as ``on_success_redirect``. Passing ``hide_sql=False`` removes the ``hide_sql`` option.
Example:
.. code-block:: python
await datasette.update_query(
database="fixtures",
name="recent_rows",
title="Latest rows",
is_private=True,
owner_id="alice",
)
.. _datasette_get_query:
await .get_query(database, name)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Returns a stored query dictionary, or ``None`` if the query does not exist.
The dictionary contains ``database``, ``name``, ``sql``, ``title``, ``description``, ``description_html``, ``hide_sql``, ``fragment``, ``parameters``, ``params``, ``is_write``, ``is_private``, ``is_trusted``, ``source``, ``owner_id``, ``on_success_message``, ``on_success_message_sql``, ``on_success_redirect``, ``on_error_message`` and ``on_error_redirect``.
``parameters`` and ``params`` contain the same list of explicit parameter names.
.. _datasette_list_queries:
await .list_queries(database=None, ...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Lists stored queries visible to the specified actor.
.. code-block:: python
async def list_queries(
self,
database=None,
*,
actor=None,
limit=50,
cursor=None,
q=None,
is_write=None,
is_private=None,
is_trusted=None,
source=None,
owner_id=None,
include_private=False,
): ...
``database`` - string, optional
Restrict results to a specific database. Omit this to list queries across all databases.
``actor`` - dictionary, optional
The authenticated actor. Results are filtered using that actor's ``view-query`` permission.
``limit`` - integer, optional
Number of queries to return. Values are clamped to the range 1-1000.
``cursor`` - string, optional
Pagination cursor from the previous page's ``next`` value.
``q`` - string, optional
Search string matched against query name, title, description and SQL.
``is_write``, ``is_private``, ``is_trusted`` - boolean, optional
Filter by those stored query flags.
``source`` - string, optional
Filter by query source.
``owner_id`` - string, optional
Filter by owner actor ID.
``include_private`` - boolean, optional
Set to ``True`` to include a ``private`` boolean in each returned query dictionary indicating if anonymous users would be unable to view that query.
The return value is a dictionary with these keys:
``queries`` - list of dictionaries
Stored query dictionaries, in the same format returned by :ref:`datasette_get_query`.
``next`` - string or None
Pagination cursor for the next page, if one exists.
``has_more`` - boolean
``True`` if another page of results is available.
``limit`` - integer
The limit used for this page.
.. _datasette_count_queries:
await .count_queries(database=None, ...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Counts stored queries visible to the specified actor. This accepts the same filtering keyword arguments as :ref:`datasette_list_queries`, except for ``limit``, ``cursor`` and ``include_private``.
.. _datasette_remove_query:
await .remove_query(database, name, source=None)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Removes a stored query.
``database`` - string
The database the query belongs to.
``name`` - string
The query name.
``source`` - string, optional
If provided, only a query with this source will be removed.
.. _datasette_column_types:
Column types
@ -2239,8 +2433,8 @@ Note that the space character is a special case: it will be replaced with a ``+`
.. _internals_utils_call_with_supported_arguments:
call_with_supported_arguments(fn, **kwargs)
-------------------------------------------
call_with_supported_arguments(fn, \*\*kwargs)
---------------------------------------------
Call ``fn``, passing it only those keyword arguments that match its function signature. This implements a dependency injection pattern - the caller provides all available arguments, and the function receives only the ones it declares as parameters.
@ -2267,8 +2461,8 @@ This is useful in plugins that want to define callback functions that only decla
.. _internals_utils_async_call_with_supported_arguments:
await async_call_with_supported_arguments(fn, **kwargs)
-------------------------------------------------------
await async_call_with_supported_arguments(fn, \*\*kwargs)
---------------------------------------------------------
Async version of :ref:`call_with_supported_arguments <internals_utils_call_with_supported_arguments>`. Use this for ``async def`` callback functions.