Stop running sqlite-utils plugins on Datasette connections

Wrapping a connection in sqlite_utils.Database() runs sqlite-utils
plugins' prepare_connection hooks against it by default. Datasette's
write API views and introspection helpers now pass execute_plugins=False
(matching what utils/internal_db.py already did), so third-party
sqlite-utils plugins no longer touch Datasette's connections.

Also apply PRAGMA recursive_triggers=on in Datasette._prepare_connection
so every connection gets consistent trigger semantics - previously only
the write connection got it, as a side effect of the first sqlite-utils
based write.

Refs #2831

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N76afGMhBRQk528VF1LTpR
This commit is contained in:
Claude 2026-07-09 06:03:42 +00:00
commit 5cec9c9faa
No known key found for this signature in database
8 changed files with 75 additions and 8 deletions

View file

@ -2782,3 +2782,38 @@ async def test_insert_with_return_failing_row_is_atomic(ds_write):
await ds_write.get_database("data").execute("select count(*) from docs")
).single_value()
assert count == 0
@pytest.mark.asyncio
async def test_write_api_does_not_run_sqlite_utils_plugins(ds_write):
# https://github.com/simonw/datasette/issues/2831
# sqlite-utils plugins should not have their prepare_connection hooks
# executed against Datasette's connections
import sqlite_utils.plugins
from sqlite_utils import hookimpl
prepared = []
class TrackingPlugin:
@hookimpl
def prepare_connection(self, conn):
prepared.append(conn)
sqlite_utils.plugins.pm.register(TrackingPlugin(), name="datasette-test-tracking")
try:
token = write_token(ds_write)
response = await ds_write.client.post(
"/data/docs/-/insert",
json={"rows": [{"id": 1, "title": "one"}]},
headers=_headers(token),
)
assert response.status_code == 201
response = await ds_write.client.post(
"/data/docs/1/-/update",
json={"update": {"title": "two"}},
headers=_headers(token),
)
assert response.status_code == 200
assert prepared == []
finally:
sqlite_utils.plugins.pm.unregister(name="datasette-test-tracking")