🤖
SQLite
Use SQLite correctly with proper concurrency, pragmas, and type handling.
安全通过
💬Prompt
技能说明
name: SQLite description: Use SQLite correctly with proper concurrency, pragmas, and type handling. metadata: {"clawdbot":{"emoji":"🪶","requires":{"bins":["sqlite3"]},"os":["linux","darwin","win32"]}}
Concurrency (Biggest Gotcha)
- Only one writer at a time—concurrent writes queue or fail; not for high-write workloads
- Enable WAL mode:
PRAGMA journal_mode=WAL—allows reads during writes, huge improvement - Set busy timeout:
PRAGMA busy_timeout=5000—waits 5s before SQLITE_BUSY instead of failing immediately - WAL needs
-waland-shmfiles—don't forget to copy them with main database BEGIN IMMEDIATEto grab write lock early—prevents deadlocks in read-then-write patterns
Foreign Keys (Off by Default!)
PRAGMA foreign_keys=ONrequired per connection—not persisted in database- Without it, foreign key constraints silently ignored—data integrity broken
- Check before relying:
PRAGMA foreign_keysreturns 0 or 1 - ON DELETE CASCADE only works if foreign_keys is ON
Type System
- Type affinity, not strict types—INTEGER column accepts "hello" without error
STRICTtables enforce types—but only SQLite 3.37+ (2021)- No native DATE/TIME—use TEXT as ISO8601 or INTEGER as Unix timestamp
- BOOLEAN doesn't exist—use INTEGER 0/1; TRUE/FALSE are just aliases
- REAL is 8-byte float—same precision issues as any float
Schema Changes
ALTER TABLEvery limited—can add column, rename table/column; that's mostly it- Can't change column type, add constraints, or drop columns (until 3.35)
- Workaround: create new table, copy data, drop old, rename—wrap in transaction
ALTER TABLE ADD COLUMNcan't have PRIMARY KEY, UNIQUE, or NOT NULL without default
Performance Pragmas
PRAGMA optimizebefore closing long-running connections—updates query planner statsPRAGMA cache_size=-64000for 64MB cache—negative = KB; default very smallPRAGMA synchronous=NORMALwith WAL—good balance of safety and speedPRAGMA temp_store=MEMORYfor temp tables in RAM—faster sorts and temp results
Vacuum & Maintenance
- Deleted data doesn't shrink file—
VACUUMrewrites entire database, reclaims space VACUUMneeds 2x disk space temporarily—ensure enough roomPRAGMA auto_vacuum=INCREMENTALwithPRAGMA incremental_vacuum—partial reclaim without full rewrite- After bulk deletes, always vacuum or file stays bloated
Backup Safety
- Never copy database file while open—corrupts if write in progress
- Use
.backupcommand in sqlite3—orsqlite3_backup_*API - WAL mode:
-waland-shmmust be copied atomically with main file VACUUM INTO 'backup.db'creates standalone copy (3.27+)
Indexing
- Covering indexes work—add extra columns to avoid table lookup
- Partial indexes supported (3.8+):
CREATE INDEX ... WHERE condition - Expression indexes (3.9+):
CREATE INDEX ON t(lower(name)) EXPLAIN QUERY PLANshows index usage—simpler than PostgreSQL EXPLAIN
Transactions
- Autocommit by default—each statement is own transaction; slow for bulk inserts
- Batch inserts:
BEGIN; INSERT...; INSERT...; COMMIT—10-100x faster BEGIN EXCLUSIVEfor exclusive lock—blocks all other connections- Nested transactions via
SAVEPOINT name/RELEASE name/ROLLBACK TO name
Common Mistakes
- Using SQLite for web app with concurrent users—one writer blocks all; use PostgreSQL
- Assuming ROWID is stable—
VACUUMcan change ROWIDs; use explicit INTEGER PRIMARY KEY - Not setting busy_timeout—random SQLITE_BUSY errors under any concurrency
- In-memory database
':memory:'—each connection gets different database; usefile::memory:?cache=sharedfor shared
如何使用「SQLite」?
- 打开小龙虾AI(Web 或 iOS App)
- 点击上方「立即使用」按钮,或在对话框中输入任务描述
- 小龙虾AI 会自动匹配并调用「SQLite」技能完成任务
- 结果即时呈现,支持继续对话优化