mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-07-23 09:24:31 +02:00
Previously query() was a generator function, so nothing - including the SQL itself - ran until the result was first iterated. A write statement passed to query() silently did nothing, and SQL errors surfaced far from the call site. The SQL now executes as soon as query() is called, while rows are still fetched lazily during iteration. Statements that return no rows now raise a ValueError directing callers to execute() instead. As a side effect, statements like INSERT ... RETURNING now work naturally with query(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UnLnhsH25Nnv7LHhekUfPd
46 lines
1.6 KiB
Python
46 lines
1.6 KiB
Python
import pytest
|
|
import sqlite3
|
|
import types
|
|
|
|
|
|
def test_query(fresh_db):
|
|
fresh_db["dogs"].insert_all([{"name": "Cleo"}, {"name": "Pancakes"}])
|
|
results = fresh_db.query("select * from dogs order by name desc")
|
|
assert isinstance(results, types.GeneratorType)
|
|
assert list(results) == [{"name": "Pancakes"}, {"name": "Cleo"}]
|
|
|
|
|
|
def test_query_executes_eagerly(fresh_db):
|
|
# The SQL runs when query() is called, not when the result is iterated,
|
|
# so errors are raised at the call site
|
|
with pytest.raises(sqlite3.OperationalError):
|
|
fresh_db.query("select * from missing_table")
|
|
|
|
|
|
def test_query_rejects_statements_that_return_no_rows(fresh_db):
|
|
fresh_db["dogs"].insert({"name": "Cleo"})
|
|
with pytest.raises(ValueError) as ex:
|
|
fresh_db.query("update dogs set name = 'Cleopaws'")
|
|
assert "execute()" in str(ex.value)
|
|
|
|
|
|
@pytest.mark.skipif(
|
|
sqlite3.sqlite_version_info < (3, 35, 0),
|
|
reason="RETURNING requires SQLite 3.35.0 or higher",
|
|
)
|
|
def test_query_insert_returning(fresh_db):
|
|
fresh_db["dogs"].insert({"name": "Cleo"})
|
|
rows = list(
|
|
fresh_db.query("insert into dogs (name) values ('Pancakes') returning name")
|
|
)
|
|
assert rows == [{"name": "Pancakes"}]
|
|
assert fresh_db["dogs"].count == 2
|
|
|
|
|
|
def test_execute_returning_dicts(fresh_db):
|
|
# Like db.query() but returns a list, included for backwards compatibility
|
|
# see https://github.com/simonw/sqlite-utils/issues/290
|
|
fresh_db["test"].insert({"id": 1, "bar": 2}, pk="id")
|
|
assert fresh_db.execute_returning_dicts("select * from test") == [
|
|
{"id": 1, "bar": 2}
|
|
]
|