sqliteproof
Find out which tables survived, not which pages broke.
SQLite's own PRAGMA integrity_check is good at detecting corruption. What it gives you is this:
*** in database main ***
Tree 25 page 35 cell 18: Offset 57005 out of range 239..4092
database disk image is malformed
That's a page number. Nobody stores data by page number. What you actually need to know at 3am is which tables can I still trust, how many rows did I lose, and is this worth restoring from backup.
$ sqliteproof app.db
app.db — DAMAGED
table verdict rows lost
------------------------------------------------------------
orders damaged 392/400 8
breaks after row 182: database disk image is malformed
audit_log intact 400/400 0
customers intact 400/400 0
1192 rows read, 8 unreadable.
Tables marked intact above are safe to export. Restore the damaged
ones from backup rather than trusting a partial read.
Install
pip install sqliteproof
Python 3.9+. No dependencies — standard library only.
Usage
sqliteproof app.db # full report
sqliteproof app.db --json # machine-readable
sqliteproof app.db --quiet # verdict line only
Exit codes: 0 intact · 1 damaged · 2 unreadable or undetermined. Drops straight into a backup script:
sqliteproof app.db --quiet || echo "corruption detected" | mail -s alert me@example.com
It opens the database read-only
A tool asked to inspect a damaged file must never be able to damage it further. The
connection is opened with mode=ro and nothing is written to the database, ever.
Runs entirely on your machine. No network, nothing uploaded.
It will not bluff
| verdict | meaning |
|---|---|
INTACT |
every table read completely and row counts match |
DAMAGED |
some rows are unreadable — with the table named and the break point located |
UNKNOWN |
the damage prevents a determination |
UNKNOWN is never dressed up as clean. A tool that reports a corrupt database as healthy
is worse than no tool.
Limitations — read these first
Structural, not semantic. It verifies rows can be read. It cannot detect corruption that produces valid-looking values — a flipped bit inside an integer that still parses is invisible to it.
Row counts come from the same damaged btree. When COUNT(*) itself fails, the expected
count is unknown and the verdict degrades to UNKNOWN rather than guessing.
It does not repair anything. It tells you what survived so you can export the good tables and restore the rest. Recovery is a different tool.
v0.1.0. Tested against databases built by SQLite and damaged at known page offsets: 3/3 corrupted databases localised to the correct table, 0 false alarms, 0 false-clean. That corpus is deliberate byte corruption, which is one failure mode among several — real corruption also arrives via truncated files, interrupted writes, and failing disks.
Tests
python sqliteproof/tests/corrupt.py # build the corpus
python sqliteproof/tests/score.py # score localisation vs ground truth
Ground truth comes from SQLite's own page allocation: tables are built one at a time and the pages added between "before" and "after" belong to that table. The file format isn't my invention and the damage lands where SQLite chose to put the data.
License
MIT.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqliteproof-0.1.0.tar.gz.
File metadata
- Download URL: sqliteproof-0.1.0.tar.gz
- Upload date:
- Size: 9.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c235512a5b7d5ca27e651c2af4484f96ca2c5f8c8c79d4808997530a77dd6b74
|
|
| MD5 |
9729f5157bfe5e19bbe5c087baf36b04
|
|
| BLAKE2b-256 |
91fb9c000d83f28089c532239444ec0107a52e52864b39c95e0f379c8882fd7b
|
File details
Details for the file sqliteproof-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sqliteproof-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b557f849fa6249f4ad0cc28756fff35e55b4cc565aee950cdc10263b5fc5361d
|
|
| MD5 |
3383e723cc0f95c955774129840374b9
|
|
| BLAKE2b-256 |
08f590fd7985cf5e1f49e949c0b13eb8310314b71ec62f998966aa8d2bd44f94
|