SQLite 3.40.0 (November 2022) introduced a public recovery API for recovering data from corrupted databases: sqlite3_recover_init(), sqlite3_recover_step(), and sqlite3_recover_finish().
The sqlite3 standard library module already wraps somewhat comparable C APIs, like Connection.backup() wraps sqlite3_backup_* or Connection.blobopen() wraps sqlite3_blob_*, although maybe none of these are as involved as the recover extension.
For recovery, users are currently required to shell out to the sqlite3 CLI binary, which is not always available. A GitHub serach for "subprocess.run" "sqlite3" ".recover" demonstrates that Python users often use subprocess to access this functionality and often have dedicated exception handling for when sqlite3 binary is absent.
Having the recovery functionality accessible from Python bindings would make downstream code more robust. Currently in Jupyter we often just drop the databases and recreate on error. Being able to recover some of the content would make it much more user friendly.
The challenge here is twofold:
- the recovery extension is not bundled in the default
sqlite3.camalgamation, although a dedicated expandedsqlite3r.camalgamation target exists since SQLite 3.41.0 - I do not know of other bindings that would ship this extension (although both Perl and Rust binding libraries were keen to explore it, the timelines did not align with when the feature was made available by SQLite)
What could be a path forward here? Is it still too early for Python to consider adding this extension?
Relevant SQLite versions:
- 3.29.0 (2019-10-04) added
.recoverCLI option - 3.40.0 (2022-11-16) added the recovery extension
- 3.41.0 (2023-02-21) added the
sqlite3r.camalgamation that includes the recovery extension.
Relevant discussions outside of Python:
- Initially, in August 2022 there was a resistance to add the recovery to public API (to discourage silent/automatic use) as seen in this thread applauding
.recoverCLI - Perl bindings (DBD-SQLite) explored it back at the time in 2022 ([feature] .recover as a driver function DBD-SQLite/DBD-SQLite#102) but owning to lack of the recovery extension they did not proceed with it
- Rust bindings (
rusqlite) explored it back in May 2023 but seemingly did not know about the newsqlite3r.camalgamation Add Recovery Extension Support rusqlite/rusqlite#1333
I was encouraged to post here, coming from Expose SQLite's `sqlite3_recover` API in `sqlite3`? · Issue #149735 · python/cpython · GitHub .