SQLite database contents is not preserved between reconnections
rutsky opened this issue · 4 comments
I'm trying to use aioodbc
for working with SQLite database and struggling with issue that database content is not preserved after closing connection.
Take a look at the following example:
import asyncio
import aioodbc
loop = asyncio.get_event_loop()
async def test_example():
dsn = 'Driver=SQLite;Database=test_db.sqlite'
async with aioodbc.connect(dsn=dsn, loop=loop) as conn:
async with await conn.cursor() as cur:
await cur.execute("CREATE TABLE test (id INTEGER PRIMARY KEY)")
await cur.execute("INSERT INTO test VALUES (1)")
await cur.execute("SELECT * FROM test")
r = await cur.fetchall()
print(r)
async with aioodbc.connect(dsn=dsn, loop=loop) as conn:
async with await conn.cursor() as cur:
# This line fails:
# pyodbc.Error: ('HY000', '[HY000] [SQLite]no such table: test (1) (1) (SQLExecDirectW)')
await cur.execute("SELECT * FROM test")
r = await cur.fetchall()
print(r)
loop.run_until_complete(test_example())
in this example I create table, insert value, close DB, then reopen DB and try to read inserted value. This fails with:
$ python test_odbc.py
[(1, )]
Traceback (most recent call last):
File "test_odbc.py", line 24, in <module>
loop.run_until_complete(test_example())
File "/usr/lib/python3.5/asyncio/base_events.py", line 387, in run_until_complete
return future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step
result = coro.send(None)
File "test_odbc.py", line 20, in test_example
await cur.execute("SELECT * FROM test")
File "/usr/lib/python3.5/asyncio/futures.py", line 361, in __iter__
yield self # This tells Task to wait for completion.
File "/usr/lib/python3.5/asyncio/tasks.py", line 296, in _wakeup
future.result()
File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result
raise self._exception
File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
result = self.fn(*self.args, **self.kwargs)
pyodbc.Error: ('HY000', '[HY000] [SQLite]no such table: test (1) (1) (SQLExecDirectW)')
Perhaps I'm missing some configuration parameter?
test_db.sqlite
file is created, but empty.
I'm running on Ubuntu 16.04 with Python 3.5 in virtualenv.
$ pip list
aioodbc (0.0.3)
pip (8.1.1)
pkg-resources (0.0.0)
pyodbc (3.0.10)
setuptools (20.7.0)
I suspect SQLite doesn't use autocommit mode by default.
@asvetlov thanks for the comment. Indeed this looks like autocommit issue, if I add
await cur.execute("COMMIT")
before closing first cursor data is being stored permanently.
Still this is counterintuitive and IMO unexpected default behavior, which is different to Python sqlite3
module behavior.
autocommit=False
is a default mode for pyodbc
, aioodbc
inherits the behavior.
You may pass autocommit=True
into aioodbc.connect()
call though.
Python's sqlite3
module will not save changes made without calling commit()
if connection is closed (so this behavior is the same as in aioodbc
), but if sqlite3
's connection is used as context manager it automatically calls commit()/rollback()
on scope exit (this behavior is different from aioodbc
).
I think it's not worth to change semantics here, so this issue is resolved.
@asvetlov thanks, settings autocommit=True
resolves this issue too.