kopia lustrzana https://github.com/simonw/datasette
db.execute_write(executescript=True) option, closes #1569
rodzic
85c22f4fbc
commit
9e094b7c9d
|
@ -94,10 +94,14 @@ class Database:
|
||||||
f"file:{self.path}{qs}", uri=True, check_same_thread=False
|
f"file:{self.path}{qs}", uri=True, check_same_thread=False
|
||||||
)
|
)
|
||||||
|
|
||||||
async def execute_write(self, sql, params=None, block=False):
|
async def execute_write(self, sql, params=None, executescript=False, block=False):
|
||||||
|
assert not (executescript and params), "Cannot use params with executescript=True"
|
||||||
def _inner(conn):
|
def _inner(conn):
|
||||||
with conn:
|
with conn:
|
||||||
return conn.execute(sql, params or [])
|
if executescript:
|
||||||
|
return conn.executescript(sql)
|
||||||
|
else:
|
||||||
|
return conn.execute(sql, params or [])
|
||||||
|
|
||||||
with trace("sql", database=self.name, sql=sql.strip(), params=params):
|
with trace("sql", database=self.name, sql=sql.strip(), params=params):
|
||||||
results = await self.execute_write_fn(_inner, block=block)
|
results = await self.execute_write_fn(_inner, block=block)
|
||||||
|
|
|
@ -663,8 +663,8 @@ Example usage:
|
||||||
|
|
||||||
.. _database_execute_write:
|
.. _database_execute_write:
|
||||||
|
|
||||||
await db.execute_write(sql, params=None, block=False)
|
await db.execute_write(sql, params=None, executescript=False, block=False)
|
||||||
-----------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
@ -676,6 +676,8 @@ By default queries are considered to be "fire and forget" - they will be added t
|
||||||
|
|
||||||
If you pass ``block=True`` this behaviour changes: the method will block until the write operation has completed, and the return value will be the return from calling ``conn.execute(...)`` using the underlying ``sqlite3`` Python library.
|
If you pass ``block=True`` this behaviour changes: the method will block until the write operation has completed, and the return value will be the return from calling ``conn.execute(...)`` using the underlying ``sqlite3`` Python library.
|
||||||
|
|
||||||
|
If you pass ``executescript=True`` your SQL will be executed using the ``sqlite3`` `conn.executescript() <https://docs.python.org/3/library/sqlite3.html#sqlite3.Cursor.executescript>`__ method. This allows multiple SQL statements to be separated by semicolons, but cannot be used with the ``params=`` option.
|
||||||
|
|
||||||
.. _database_execute_write_fn:
|
.. _database_execute_write_fn:
|
||||||
|
|
||||||
await db.execute_write_fn(fn, block=False)
|
await db.execute_write_fn(fn, block=False)
|
||||||
|
|
|
@ -396,6 +396,27 @@ async def test_execute_write_block_false(db):
|
||||||
assert "Mystery!" == rows.rows[0][0]
|
assert "Mystery!" == rows.rows[0][0]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_execute_write_executescript(db):
|
||||||
|
await db.execute_write(
|
||||||
|
"create table foo (id integer primary key); create table bar (id integer primary key); ",
|
||||||
|
executescript=True,
|
||||||
|
block=True
|
||||||
|
)
|
||||||
|
table_names = await db.table_names()
|
||||||
|
assert {"foo", "bar"}.issubset(table_names)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_execute_write_executescript_not_allowed_with_params(db):
|
||||||
|
with pytest.raises(AssertionError):
|
||||||
|
await db.execute_write(
|
||||||
|
"update roadside_attractions set name = ? where pk = ?",
|
||||||
|
["Mystery!", 1],
|
||||||
|
executescript=True
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_execute_write_has_correctly_prepared_connection(db):
|
async def test_execute_write_has_correctly_prepared_connection(db):
|
||||||
# The sleep() function is only available if ds._prepare_connection() was called
|
# The sleep() function is only available if ds._prepare_connection() was called
|
||||||
|
|
Ładowanie…
Reference in New Issue