I'm working with an SQLite database using the Python apsw bindings. The code goes like this:
with apsw.Connection(path) as t:
c = t.cursor()
c.execute(...)
... more code ...
if c.execute(...).next()[0]:
raise Exception
I expect the with
statement to put a savepoint and the raise
statement to rollback to that savepoint (or, if there's nothing to raise, commit the transaction). It commits just fine, but when there's something to raise
it refuses to rollback with:
BusyError: BusyError: cannot rollback savepoint - SQL statements in progress
I'm not sure where to look first. As far as I understand the error means there's another connection that blocks the access, but this doesn't look so from the code, and, if this was so, wouldn't it fail on commits as well?
SQLite 3.7.7.1, matching apsw
, Python 2.7.
Well, I found it:
if c.execute(...).next()[0]:
raise Exception
The problem is that at the moment I get the next row with next()
, the underlying cursor stays active, ready to return more rows. It has to be closed explicitly:
if c.execute(...).next()[0]:
c.close()
raise Exception
or implicitly, by reading out all data:
if list(c.execute(...))[0][0]:
raise Exception
UPDATE. For convenience I wrote a Python class that wraps apsw.Cursor
and provides a context manager, so I can write:
with Cursor(connection) as c:
c.execute(...)