From 11fc2d16c9697c82607a0ffcdd5e13b724f09eea Mon Sep 17 00:00:00 2001 From: KooshaPari Date: Sat, 12 Sep 2026 23:09:55 -0700 Subject: [PATCH] fix: add transaction guard to vacuum() method (fixes #479) --- sqlite_utils/db.py | 11 +++++++++-- tests/test_atomic.py | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index c011d9bb0..b85e1ebb6 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -2024,8 +2024,15 @@ def index_foreign_keys(self) -> None: existing_indexes.add(fk_columns) def vacuum(self) -> None: - "Run a SQLite ``VACUUM`` against the database." - self.execute("VACUUM;") + """ + Run a SQLite ``VACUUM`` against the database. + + :raises TransactionError: if called while a transaction is open - VACUUM + cannot run inside a transaction + """ + self._ensure_no_open_transaction("vacuum()") + with self.ensure_autocommit_on(): + self.execute("VACUUM;") def analyze(self, name: str | None = None) -> None: """ diff --git a/tests/test_atomic.py b/tests/test_atomic.py index 89a318adf..2e887bdbb 100644 --- a/tests/test_atomic.py +++ b/tests/test_atomic.py @@ -1,6 +1,6 @@ import pytest -from sqlite_utils.db import Database, _iter_complete_sql_statements +from sqlite_utils.db import Database, TransactionError, _iter_complete_sql_statements from sqlite_utils.utils import sqlite3 @@ -381,3 +381,18 @@ def test_atomic_preserves_error_from_insert_or_rollback(fresh_db): with pytest.raises(sqlite3.IntegrityError), fresh_db.atomic(): fresh_db.execute("insert or rollback into t (id) values (1)") assert not fresh_db.conn.in_transaction + + +def test_vacuum_raises_transaction_error_inside_atomic(fresh_db): + """Test that vacuum() raises TransactionError when called inside atomic()""" + fresh_db.table("t").insert({"id": 1}, pk="id") + with pytest.raises(TransactionError, match="vacuum\\(\\)"): + with fresh_db.atomic(): + fresh_db.vacuum() + + +def test_vacuum_works_outside_atomic(fresh_db): + """Test that vacuum() works when called outside a transaction""" + fresh_db.table("t").insert({"id": 1}, pk="id") + fresh_db.vacuum() + assert list(fresh_db.table("t").rows) == [{"id": 1}]