From bd77a536bca08fd063f53f9012b080e028395ff9 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Fri, 8 May 2020 15:14:53 +0000 Subject: [PATCH] Documentation for design of .execute() and Results, refs #685 --- docs/internals.rst | 57 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/docs/internals.rst b/docs/internals.rst index d7b6e7cb42..9a2cfe5bba 100644 --- a/docs/internals.rst +++ b/docs/internals.rst @@ -96,6 +96,63 @@ Instances of the ``Database`` class can be used to execute queries against attac SQLite only allows one database connection to write at a time. Datasette handles this for you by maintaining a queue of writes to be executed against a given database. Plugins can submit write operations to this queue and they will be executed in the order in which they are received. +.. _database_execute: + +await db.execute(sql, ...) +-------------------------- + +Executes a SQL query against the database and returns the resulting rows (see :ref:`database_results`). + +``sql`` - string (required) + The SQL query to execute. This can include ``?`` or ``:named`` parameters. + +``params`` - list or dict + A list or dictionary of values to use for the parameters. List for ``?``, dictionary for ``:named``. + +``truncate`` - boolean + Should the rows returned by the query be truncated at the maximum page size? Defaults to ``True``, set this to ``False`` to disable truncation. + +``custom_time_limit`` - integer ms + A custom time limit for this query. This can be set to a lower value than the Datasette configured default. If a query takes longer than this it will be terminated early and raise a ``dataette.utils.QueryInterrupted`` exception. + +``page_size`` - integer + Set a custom page size for truncation, over-riding the configured Datasette default. + +``log_sql_errors`` - boolean + Should any SQL errors be logged to the console in addition to being raised as an error? Defaults to ``True``. + +.. _database_results: + +Results +------- + +The ``db.execute()`` method returns a single ``Results`` object. This can be used to access the rows returned by the query. + +Iterating over a ``Results`` object will yield SQLite `Row objects `__. These can be treated as a tuple or can be accessed using ``row["column"]`` syntax: + +.. code-block:: python + + info = [] + results = await db.execute("select name from sqlite_master") + for row in results: + info.append(row["name"]) + +The ``Results`` object also has the following properties and methods: + +``.truncated`` - boolean + Indicates if this query was truncated - if it returned more results than the specified ``page_size``. If this is true then the results object will only provide access to the first ``page_size`` rows in the query result. You can disable truncation by passing ``truncate=False`` to the ``db.query()`` method. + +``.columns`` - list of strings + A list of column names returned by the query. + +``.first()`` - row or None + Returns the first row in the results, or ``None`` if no rows were returned. + +``.single_value()`` + Returns the value of the first column of the first row of results - but only if the query returned a single row with a single column. Raises a ``MultipleValues`` exception otherwise. + +You can directly access rows by index using ``results[0]`` + .. _database_execute_write: await db.execute_write(sql, params=None, block=False)