Python SQLite With Block Leaves the Connection Open: Close It Explicitly
By ON Lab · Sources checked November 9, 2026
Separate transaction completion from resource cleanup. The connection context handles transaction outcomes; add an explicit close boundary for the connection lifetime.
Reproduce the boundary in a disposable example
A sqlite3 connection still accepts queries after leaving its with block.
import sqlite3
from contextlib import closing
connection = sqlite3.connect(":memory:")
with connection:
connection.execute("create table sample(value integer)")
assert connection.execute("select 1").fetchone() == (1,)
connection.close()
try:
connection.execute("select 1")
except sqlite3.ProgrammingError:
pass
else:
raise AssertionError("connection should be closed")
with closing(sqlite3.connect(":memory:")) as managed:
with managed:
managed.execute("create table sample(value integer)")
print("transaction and close boundaries verified")Read the result before changing application code
The query after the first with block is an intentional lifetime probe, not a transaction durability test. The in-memory database keeps this demonstration isolated from real data. The final nested structure expresses both boundaries: the inner context handles the transaction and the outer closing context releases the connection.
Choose the behavior your caller needs
Use try/finally with close if explicit cleanup is clearer. Never close a borrowed connection that a pool or caller still owns. For file-lock problems, also inspect cursors, transactions and other processes; an open connection alone is not a complete diagnosis. Test success and exception paths. Confirm commit or rollback behavior with the transaction settings actually used by your application.
Scope and limits
The example does not claim all transaction modes behave identically. An autocommit connection and Python’s newer autocommit options need separate transaction-policy review.
Related: compare the adjacent data or execution boundary.
The embedded example was executed in an isolated local Python process on November 9, 2026. It is a reproducible boundary check, not a test of your full application.