Skip to content

Committed changes can be rolled back after switching autocommit off #13

@yeongseon

Description

@yeongseon

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:

  1. perform autocommit writes
  2. set autocommit = False
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions