Database() now accepts all three Python transaction handling modes and
behaves identically in each. For autocommit=False connections - where
the driver holds an implicit transaction open at all times - the
library tracks transaction ownership itself:
- A new _explicit_transaction flag distinguishes transactions opened
with begin()/atomic() from the driver's implicit one, exposed as a
new db.in_transaction property (conn.in_transaction is always True
in this mode)
- begin() claims the driver's implicit transaction instead of
executing BEGIN, which the driver would reject; BEGIN/COMMIT/
ROLLBACK passed to db.execute() are routed through begin()/commit()/
rollback()
- Writes outside a user transaction commit the implicit transaction
immediately, preserving the library's auto-commit contract
- Row-returning statements outside a transaction fetch eagerly and
commit, so the implicit read transaction does not hold a shared
lock that blocks writes from other connections
- PRAGMA and VACUUM run in temporary driver autocommit mode
(ensure_autocommit_on() now flips conn.autocommit), since PRAGMAs
are silently ignored and VACUUM refused inside the implicit
transaction
A new pytest --sqlite-autocommit-false option runs the entire suite
in this mode, wired into CI alongside --sqlite-autocommit. Tests that
asserted on conn.in_transaction or wrote through db.conn without
committing now use the mode-aware library API instead.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PFkrS2nuP8mo1jmT594VCd
* Fix transform() corrupting TRUE/FALSE/NULL column defaults
quote_default_value() passed keyword-literal defaults (TRUE, FALSE, NULL)
through self.quote(), wrapping them in quotes. So transform() rebuilt a
column declared "INTEGER DEFAULT TRUE" as "INTEGER DEFAULT 'TRUE'", and a
later default insert stored the text 'TRUE' instead of the integer 1
(likewise 'FALSE' for 0 and 'NULL' for null) - silent value corruption.
Return these keyword literals unquoted, as already done for the
CURRENT_TIME/DATE/TIMESTAMP literals.
PR #764
* Recreate indexes when calling transform when possible and raise an error when they cannot be retained automatically
* Docs for sqlite_utils.db.TransformError
Co-authored-by: Simon Willison <swillison@gmail.com>
Closes#577
This should solve all sorts of problems seen by users of platforms that throw errors on writable_schema.
Also added `add_foreign_keys=` and `foreign_keys=` parameters to `table.transform()`.