Skilllibrary sqlite
install
source · Clone the upstream repo
git clone https://github.com/merceralex397-collab/skilllibrary
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/merceralex397-collab/skilllibrary "$T" && mkdir -p ~/.claude/skills && cp -r "$T/09-backend-api-and-data/sqlite" ~/.claude/skills/merceralex397-collab-skilllibrary-sqlite && rm -rf "$T"
manifest:
09-backend-api-and-data/sqlite/SKILL.mdsource content
Purpose
Provide concrete guidance for configuring, querying, and operating SQLite databases in application code. SQLite has fundamentally different concurrency, deployment, and operational characteristics from server databases. This skill encodes those differences so agents produce correct PRAGMA settings, safe migration strategies, and appropriate concurrency patterns instead of treating SQLite like a lightweight PostgreSQL.
When to use this skill
Use this skill when:
- configuring SQLite PRAGMA settings (journal_mode, synchronous, foreign_keys, busy_timeout)
- implementing concurrent access patterns for SQLite (WAL mode, reader/writer coordination)
- writing application-level migrations for SQLite (no transactional DDL for some operations)
- using SQLite extensions: JSON1 for JSON queries, FTS5 for full-text search
- building embedded databases, test fixtures, CLI tool storage, or mobile local storage
- deciding whether SQLite is appropriate vs a server database for a given workload
Do not use this skill when
- the database is PostgreSQL, MySQL, or another server database — use
or the appropriate skillpostgresql - the task involves connection pooling, replication, or multi-server architectures
- the workload requires concurrent writes from multiple processes (SQLite is single-writer)
- the task is about ORM-level patterns (model definitions, eager loading) — use
orm-patterns
Operating procedure
- Determine the deployment context. Is this embedded (mobile, desktop, CLI), test harness, or single-server web app? This determines concurrency requirements and PRAGMA choices.
- Enable WAL mode immediately. Unless there is a specific reason for rollback journal (e.g., read-only media), always use WAL:
PRAGMA journal_mode = WAL; - Set essential PRAGMAs at connection open. These must be set per-connection, not once globally:
PRAGMA journal_mode = WAL; -- write-ahead logging PRAGMA synchronous = NORMAL; -- safe with WAL, faster than FULL PRAGMA foreign_keys = ON; -- off by default! PRAGMA busy_timeout = 5000; -- wait 5s on lock instead of failing immediately PRAGMA cache_size = -64000; -- 64MB page cache (negative = KB) PRAGMA wal_autocheckpoint = 1000; -- checkpoint every 1000 pages - Design for single-writer concurrency. WAL allows concurrent reads with one writer. Structure application code so writes go through a single connection or serialized write queue. Multiple readers can use separate connections.
- Write migrations as numbered SQL files. SQLite does not support transactional DDL for all operations (e.g.,
is limited). Some schema changes require the 12-step migration: create new table, copy data, drop old, rename new.ALTER TABLE - Use appropriate column types. SQLite uses dynamic typing but declare types for documentation and ORM compatibility. Use
for rowid alias (auto-increment). UseINTEGER PRIMARY KEY
for dates in ISO 8601 format.TEXT - Leverage JSON1 for flexible metadata. Store structured metadata as JSON in TEXT columns, query with
,json_extract()
, andjson_each()
.json_tree() - Use FTS5 for full-text search. Create virtual tables with
module for fast text search instead offts5
scans.LIKE '%query%' - Implement backup strategies. Use
API for hot backups or.backup
for compacted copies. Never copy the file directly while connections are open.VACUUM INTO 'backup.db' - Verify with integrity checks. Run
after migrations and periodically in production.PRAGMA integrity_check
Decision rules
- WAL vs rollback journal: Use WAL unless the database is on read-only media, shared via NFS (WAL requires shared memory), or you need strict serialization of all access.
- synchronous = NORMAL vs FULL: NORMAL is safe with WAL mode (transactions survive process crash but not OS crash). Use FULL only if you cannot tolerate any data loss on power failure.
- SQLite vs server database: Use SQLite when the workload is single-writer, data fits on one machine, there is no need for concurrent write scaling, and deployment simplicity matters. Switch to PostgreSQL when you need concurrent writes from multiple processes, replication, or row-level locking.
- JSON column vs separate table: Use JSON1 for semi-structured metadata queried occasionally. Use normalized tables for data that appears in WHERE clauses, JOINs, or needs indexing.
- FTS5 vs LIKE: Use FTS5 for any text search on more than a few thousand rows.
forces full table scan and cannot use indexes.LIKE '%term%' - In-memory vs file-backed: Use
or:memory:
for test fixtures and ephemeral data. Use file-backed for anything that must survive process restart.file::memory:
Anti-patterns
- Not setting
: SQLite disables foreign key enforcement by default. Every connection must enable it explicitly or FK constraints are silently ignored.foreign_keys = ON - Opening multiple write connections: SQLite allows only one writer at a time. Multiple write connections cause
errors. Use a single write connection with a queue or mutex.SQLITE_BUSY - Using
in a transaction: Journal mode changes must happen outside any transaction. Setting it insidePRAGMA journal_mode
is silently ignored.BEGIN...COMMIT - Copying the database file while in use: Without using the backup API, this can produce a corrupt copy. Use
,.backup
, orVACUUM INTO
.sqlite3_backup_init()
assumptions from PostgreSQL: SQLite'sALTER TABLE
only supportsALTER TABLE
,RENAME TABLE
,RENAME COLUMN
, andADD COLUMN
(3.35+). NoDROP COLUMN
, noALTER COLUMN
.ADD CONSTRAINT- Not setting
: Without it, any lock contention immediately returnsbusy_timeout
. Set at least 1000-5000ms.SQLITE_BUSY - Storing large blobs: SQLite page size defaults to 4KB. Large blobs fragment across many pages and slow down reads. Keep blobs under 100KB or use external files with path references.
- Using
unnecessarily:AUTOINCREMENT
already auto-increments via rowid. AddingINTEGER PRIMARY KEY
prevents reuse of deleted rowids but adds overhead and a separate tracking table.AUTOINCREMENT
Output requirements
— Exact PRAGMA statements with rationale for each settingPRAGMA Configuration
— CREATE TABLE statements with appropriate types and constraintsSchema DDL
— Numbered migration files, noting SQLite-specific limitationsMigration Plan
— How readers and writers are coordinated in the applicationConcurrency Model
— PRAGMA checks and integrity verification commandsValidation
References
Read these when relevant to the specific task:
— WAL setup, connection management, migrations, JSON1/FTS5, backupsreferences/implementation-patterns.md
— PRAGMA verification, FK enforcement, WAL checkpoints, integrity checksreferences/validation-checklist.md
— SQLITE_BUSY, locked database, corrupt journal, WAL growth, disk fullreferences/failure-modes.md
Related skills
— When the workload outgrows SQLite's single-writer modelpostgresql
— When using SQLAlchemy, Django ORM, or Prisma with SQLite as backendorm-patterns
— When designing entity relationships that will be stored in SQLitedata-model
— When using SQLite as a job queue backendbackground-jobs-queues
Failure handling
- SQLITE_BUSY (error 5): Another connection holds a write lock. Verify
is set. Check for long-running write transactions. Ensure single-writer pattern is enforced.busy_timeout - Database locked: A process has an exclusive lock (during checkpoint or VACUUM). Wait and retry. Check if WAL checkpoint is stuck.
- Corrupt database: Run
. If corruption is confirmed, restore from backup. Investigate cause: disk failure, incomplete write, NFS usage.PRAGMA integrity_check - WAL file growing unbounded: Checkpointing is not running. Check
setting. Runwal_autocheckpoint
manually. Verify no long-running read transactions blocking checkpoint.PRAGMA wal_checkpoint(TRUNCATE) - Migration failed: SQLite has limited
. If a migration requires column type change or constraint addition, use the 12-step migration pattern (create new table → copy data → drop old → rename).ALTER TABLE - Disk full during write: SQLite will return
. The transaction is rolled back. Free disk space and retry. Check WAL file size — it may be consuming unexpected space.SQLITE_FULL