Summary
ExcelConnection stores an in-memory snapshot at construction time and refreshes it on commit(), but autocommit write paths save the workbook without updating that snapshot.
Because autocommit is a mutable public attribute, a caller can:
- perform autocommit writes
- set
autocommit = False
- call
rollback()
and unexpectedly revert changes that were already committed to disk.
Code references
src/excel_dbapi/connection.py
src/excel_dbapi/cursor.py
Relevant behavior:
self._snapshot = self.engine.snapshot()
but in autocommit execute/executemany:
if self.connection.autocommit and result.action in {...}:
self.connection.engine.save()
No snapshot refresh happens after the save.
Reproduction
from pathlib import Path
from openpyxl import Workbook, load_workbook
from excel_dbapi.connection import ExcelConnection
import tempfile
with tempfile.TemporaryDirectory() as td:
path = Path(td) / 'sample.xlsx'
wb = Workbook()
ws = wb.active
ws.title = 'Sheet1'
ws.append(['id', 'name'])
ws.append([1, 'Alice'])
wb.save(path)
conn = ExcelConnection(str(path), engine='openpyxl', autocommit=True)
cur = conn.cursor()
cur.execute("INSERT INTO Sheet1 (id, name) VALUES (2, 'Bob')")
conn.autocommit = False
conn.rollback()
conn.commit()
conn.close()
wb2 = load_workbook(path, data_only=True)
print(list(wb2['Sheet1'].iter_rows(values_only=True)))
Actual output:
[('id', 'name'), (1, 'Alice')]
The already-committed Bob row disappears.
Expected
Once an autocommit write is saved, later rollback should not revert it. The snapshot should be refreshed after autocommit saves, or autocommit should be made immutable for the lifetime of a connection.
Summary
ExcelConnectionstores an in-memory snapshot at construction time and refreshes it oncommit(), but autocommit write paths save the workbook without updating that snapshot.Because
autocommitis a mutable public attribute, a caller can:autocommit = Falserollback()and unexpectedly revert changes that were already committed to disk.
Code references
src/excel_dbapi/connection.pysrc/excel_dbapi/cursor.pyRelevant behavior:
but in autocommit execute/executemany:
No snapshot refresh happens after the save.
Reproduction
Actual output:
The already-committed
Bobrow disappears.Expected
Once an autocommit write is saved, later rollback should not revert it. The snapshot should be refreshed after autocommit saves, or autocommit should be made immutable for the lifetime of a connection.