Skip to content

v0.2.4 — the pip module speaks Django's sqlite3

Choose a tag to compare

@punnerud punnerud released this 02 Aug 10:57
· 126 commits to main since this release

Verified on Linux x86-64, macOS/Apple Silicon and Windows x86-64 — tests, clippy and the crash harnesses green on all three. Prebuilt binaries attached (CLI for all three platforms + the sqlite3 drop-in shim; sha256sums below).

The pip install mpedb module speaks Django's sqlite3

The first real Django 4.2 project switched onto the Python module (the sys.modules swap route, as opposed to the LD_PRELOAD shim) logged five precise blockers. All five close in this release, each verified against the log's own repro and pinned in the module's suite (28 → 34 checks):

  1. Connection and Cursor are subclassable, and cursor(factory=...) instantiates the subclass — Django's backend defines SQLiteCursorWrapper(Database.Cursor) at import time and could not even load before.
  2. mpedb.adapt() exists, and the adapter chain (registered adapter for the exact type → __conform__ → named refusal) runs at bind time for non-base types — Django's own date/datetime/Decimal adapters win, exactly as in the stdlib.
  3. file:X?mode=memory&cache=shared (with uri=True) is now a real shared in-memory database — it used to silently become a preallocated 64 MiB file on disk in the consumer's working directory. Unsupported URI parameters refuse by name.
  4. Reads see your own uncommitted writes on the native engine: the connection's transaction is a real write session now (the old design buffered statements until commit, so a SELECT inside a transaction returned nothing for rows the same connection had just written — fatal for Django's TestCase, which wraps every test in a transaction it rolls back). Errors surface at execute(); holding the writer lock across the transaction is sqlite's own model.
  5. The missing surface: create_function (with deterministic), create_aggregate, create_collation, executescript (quote/comment-aware script splitting; trigger bodies carved whole), isolation_level (None = autocommit, explicit BEGIN/COMMIT/ROLLBACK drive the real transaction), in_transaction, cursor.lastrowid, and mpedb.Row + row_factory.

The PyPI wheels of this version are the first where the swap route can run a Django project's test suite; the LD_PRELOAD shim route was already there (see v0.2.2/v0.2.3).

Attached binaries

file contents
mpedb-0.2.4-linux-x86_64.tar.gz mpedb CLI, Linux x86-64
mpedb-0.2.4-macos-arm64.tar.gz mpedb CLI, macOS Apple Silicon
mpedb-0.2.4-windows-x86_64.zip mpedb.exe, Windows x86-64
libmpedb_sqlite3-0.2.4-linux-x86_64.tar.gz sqlite3 drop-in shim, Linux
libmpedb_sqlite3-0.2.4-macos-arm64.tar.gz sqlite3 drop-in shim, macOS
SHA256SUMS checksums for everything above