Repository navigation
|
Context: A new requirement has been introduced that makes the main process write to duckdb before the workers start, but after the transaction has started. Issue: Here's a short demo without all the threading abstracted: #!/usr/bin/env python
import duckdb
con = duckdb.connect()
con.execute("CREATE TABLE t(i INTEGER)")
con.begin()
con.execute("INSERT INTO t VALUES (1)")
parent_count = con.execute("SELECT COUNT(*) FROM t").fetchone()[0]
cursor = con.cursor()
cursor_count_before_commit = cursor.execute("SELECT COUNT(*) FROM t").fetchone()[0]
con.commit()
cursor_count_after_commit = cursor.execute("SELECT COUNT(*) FROM t").fetchone()[0]
print(f"DuckDB version: {duckdb.__version__}")
print(f"Parent connection count inside transaction: {parent_count}")
print(f"cursor() count before parent commit: {cursor_count_before_commit}")
print(f"cursor() count after parent commit: {cursor_count_after_commit}")
assert parent_count == 1
assert cursor_count_before_commit == 0
assert cursor_count_after_commit == 1I'm unsure if this is expected behavior. |
Replies: 2 comments
|
Yes, this is expected. I ran your example on DuckDB 2.0.0 / Python 3.14.7 and got There is one extra distinction: your cursor is in autocommit mode. If it explicitly begins a transaction and reads before the parent's commit, further reads keep that earlier snapshot until the cursor ends its transaction. I checked that case too. For your threaded workflow:
The current Python API docs now explicitly describe the independent transaction, and the threading guide calls for a separate connection per thread. So your proposed interpretation as a separate connection is the right one. |
|
The reply above is right, thanks nazeeh111. I checked it on 2.0.0 and on main: |
Yes, this is expected.
con.cursor()creates a separate connection to the same database, with its own transaction. It does not join the transaction started bycon.begin().I ran your example on DuckDB 2.0.0 / Python 3.14.7 and got
1, 0, 1: the parent sees its own uncommitted insert, the cursor cannot see it before the parent commits, and its next query sees it after the commit.There is one extra distinction: your cursor is in autocommit mode. If it explicitly begins a transaction and reads before the parent's commit, further reads keep that earlier snapshot until the cursor ends its transaction. I checked that case too.
For your threaded workflow: