mirror of
https://github.com/simonw/datasette.git
synced 2026-06-05 16:46:57 +02:00
RenameTableEvent, plus write connection track_event() mechanism (#2682)
* Add track_event callback to execute_write_fn and write_wrapper Allows write functions and write_wrapper generators to queue events during a write operation that are dispatched after successful commit. The fn or wrapper can optionally accept a `track_event` parameter (detected via call_with_supported_arguments). Events are discarded if the write raises an exception. Does not yet handle the block=False (non-blocking) case - events queued during non-blocking writes are currently silently discarded. Refs https://github.com/simonw/datasette/issues/2681 * Dispatch track_event events for non-blocking (block=False) writes Spawns a background asyncio task that awaits the write thread's reply queue and dispatches pending events after a successful non-blocking write. Events are still discarded if the write raises an exception. Refs https://github.com/simonw/datasette/issues/2681 * Warn that events won't fire for other processes Refs https://github.com/simonw/datasette/issues/2681#issuecomment-4157118662
This commit is contained in:
parent
9b5cb1347c
commit
312f41b0c2
8 changed files with 423 additions and 24 deletions
|
|
@ -5,6 +5,8 @@ Datasette includes a mechanism for tracking events that occur while the software
|
|||
|
||||
The core Datasette application triggers events when certain things happen. This page describes those events.
|
||||
|
||||
Note that these events will *not* fire for changes made to a SQLite database by a process other than Datasette itself.
|
||||
|
||||
Plugins can listen for events using the {ref}`plugin_hook_track_event` plugin hook, which will be called with instances of the following classes - or additional classes {ref}`registered by other plugins <plugin_hook_register_events>`.
|
||||
|
||||
```{eval-rst}
|
||||
|
|
|
|||
|
|
@ -1739,6 +1739,36 @@ For example:
|
|||
except Exception as e:
|
||||
print("An error occurred:", e)
|
||||
|
||||
Your function can optionally accept a ``track_event`` parameter in addition to ``conn``. If it does, it will be passed a callable that can be used to queue events for dispatch after the write transaction commits successfully. Events queued this way are discarded if the write raises an exception.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from datasette.events import AlterTableEvent
|
||||
|
||||
|
||||
def my_write(conn, track_event):
|
||||
before_schema = conn.execute(
|
||||
"select sql from sqlite_master where name = 'my_table'"
|
||||
).fetchone()[0]
|
||||
conn.execute(
|
||||
"alter table my_table add column new_col text"
|
||||
)
|
||||
after_schema = conn.execute(
|
||||
"select sql from sqlite_master where name = 'my_table'"
|
||||
).fetchone()[0]
|
||||
track_event(
|
||||
AlterTableEvent(
|
||||
actor=None,
|
||||
database="mydb",
|
||||
table="my_table",
|
||||
before_schema=before_schema,
|
||||
after_schema=after_schema,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
await database.execute_write_fn(my_write)
|
||||
|
||||
The value returned from ``await database.execute_write_fn(...)`` will be the return value from your function.
|
||||
|
||||
If your function raises an exception that exception will be propagated up to the ``await`` line.
|
||||
|
|
|
|||
|
|
@ -78,12 +78,14 @@ write_wrapper(datasette, database, request, transaction)
|
|||
``transaction`` - bool
|
||||
``True`` if the write will be wrapped in a database transaction.
|
||||
|
||||
Return a generator function that accepts a ``conn`` argument (a SQLite connection object). The generator should ``yield`` exactly once. Code before the ``yield`` runs before the write function executes; code after the ``yield`` runs after it completes.
|
||||
Return a generator function that accepts a ``conn`` argument (a SQLite connection object) and optionally a ``track_event`` argument. The generator should ``yield`` exactly once. Code before the ``yield`` runs before the write function executes; code after the ``yield`` runs after it completes.
|
||||
|
||||
The result of the write function is sent back through the ``yield``, so you can capture it with ``result = yield``.
|
||||
|
||||
If the write function raises an exception, it is thrown into the generator so you can handle it with a ``try`` / ``except`` around the ``yield``.
|
||||
|
||||
If your generator accepts ``track_event``, you can call ``track_event(event)`` to queue an event that will be dispatched via :ref:`datasette.track_event() <datasette_track_event>` after the write commits successfully. Events are discarded if the write raises an exception.
|
||||
|
||||
Return ``None`` to skip wrapping for this particular write.
|
||||
|
||||
This example logs every write operation:
|
||||
|
|
|
|||
|
|
@ -261,7 +261,8 @@ If you run ``datasette plugins --all`` it will include default plugins that ship
|
|||
"templates": false,
|
||||
"version": null,
|
||||
"hooks": [
|
||||
"register_events"
|
||||
"register_events",
|
||||
"write_wrapper"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue