Skip to main content

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

sqliteproof-0.1.0.tar.gz (9.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sqliteproof-0.1.0-py3-none-any.whl (9.4 kB view details)

Uploaded Python 3

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

Hashes for sqliteproof-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c235512a5b7d5ca27e651c2af4484f96ca2c5f8c8c79d4808997530a77dd6b74
MD5 9729f5157bfe5e19bbe5c087baf36b04
BLAKE2b-256 91fb9c000d83f28089c532239444ec0107a52e52864b39c95e0f379c8882fd7b

See more details on using hashes here.

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

Hashes for sqliteproof-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b557f849fa6249f4ad0cc28756fff35e55b4cc565aee950cdc10263b5fc5361d
MD5 3383e723cc0f95c955774129840374b9
BLAKE2b-256 08f590fd7985cf5e1f49e949c0b13eb8310314b71ec62f998966aa8d2bd44f94

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.1

2 files

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page