drizzle-sqlite について
SQLite系バックエンドでDrizzle ORMを使う開発者向けのリファレンススキルです。スキーマ、マイグレーション、クエリ、アプリケーションの型を扱い、複数のドライバーとSQLite固有の挙動を45のルールで解説します。
主な機能
- 018カテゴリ、45のルール
- 02スキーマとマイグレーションの指針
- 03クエリとリレーションのパターン
- 04トランザクションとバッチ処理
- 05ドライバー設定と型推論
活用シーン
- 01SQLiteのスキーマとインデックスの設計
- 02Drizzleのマイグレーション計画
- 03クエリ性能の改善
- 04トランザクションとドライバー接続の設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill drizzle-sqliteインストール後、Claude Code で/drizzle-sqliteを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdmetadata.jsonassets/templates/_template.mdreferences/_sections.mdconn-enable-wal.mdconn-foreign-keys-pragma.mdconn-pick-driver-deliberately.mdconn-set-busy-timeout.mdconn-singleton-client.mdmigrate-apply-with-migrator.mdmigrate-commit-migrations-to-git.mdmigrate-config-dialect-and-out.mdmigrate-data-backfill-as-custom-sql.mdmigrate-explicit-renames.mdmigrate-generate-not-push-in-prod.mdperf-avoid-count-star-on-large-tables.mdperf-bulk-insert-multi-row-values.mdperf-covering-index-for-hot-queries.mdperf-keyset-not-offset-for-deep-pages.mdperf-prepare-hot-paths.mdquery-always-limit-listings.mdquery-avoid-n-plus-one-with-inarray.mdquery-bind-parameters-not-concat.mdquery-returning-instead-of-reselect.mdquery-select-columns-not-star.mdquery-toSQL-and-explain.mdquery-upsert-with-onconflict.mdrel-declare-relations-for-rqb.mdrel-filter-with-where-inside-with.mdrel-leftjoin-for-flat-aggregates.md詳細
dot-skills Drizzle SQLite ベストプラクティス
SQLite 系バックエンドで Drizzle ORM を使うためのライブラリリファレンススキルです。8 つのカテゴリーにわたる 45 のルールを、実行ライフサイクルへの影響が大きい順に並べています:スキーマ → マイグレーション → クエリ → リレーション → トランザクション → パフォーマンス → 接続 → 型。
適用するタイミング
次のような場合に、このガイドラインを参照してください:
sqliteTableスキーマを定義するとき — カラム型、主キー、インデックス、外部キーの選択drizzle-kit generate/migrate/pushを実行するとき、またはマイグレーション SQL ファイルを手動で編集するときdb.select()、db.insert()、db.update()、db.delete()を使ってクエリを書くときdb.query.*とリレーショナルクエリビルダーを使ってネストされたデータを取得するとき- 複数ステートメントの書き込みを
db.transaction()またはdb.batch()(libsql/Turso/D1)でまとめるとき .prepare()とsql.placeholder()、またはカバリングインデックスを使ってホットパスのクエリを最適化するとき- Drizzle クライアントを設定するとき(プラグマ、ドライバーの選択、シングルトンのライフサイクル)
- データベースの型をアプリケーションコードに組み込むとき(
$inferSelect、drizzle-zod、JSON の形状)
このスキルは特定のドライバーに限定されません。better-sqlite3、libsql、bun:sqlite、expo-sqlite、op-sqlite、Cloudflare D1 に共通する動作を扱い、ドライバー固有の違いがある場合はその旨を示します。
アーキテクチャ上の背景
SQLite は、本番データベースとしては独特な特徴があります:
- クライアント/サーバー型ではありません。 「接続」とはファイルを開くことです。ローカルファイルの場合、接続プールも認証もネットワークもありません。
- ライターは 1 つです。 接続数にかかわらず、同時に書き込めるのは 1 つだけです。WAL を使えば、読み取りは並列に実行できます。
- ネイティブなブール値や日付はありません。 すべて
INTEGER、REAL、TEXT、BLOB、またはNULLです。残りの型は Drizzle のカラムモードで表現します。 ALTER TABLEの機能は限定的です。 可能なのはRENAME COLUMN、ADD COLUMN、DROP COLUMNのみです。型の変更や制約の追加には、テーブルの再構築が必要です。- 外部キーはデフォルトで無効です。
PRAGMA foreign_keys = ONは接続ごとの設定で、永続化されません。
このスキルに多くのルールがあるのは、Drizzle の API が PostgreSQL/MySQL/SQLite を統一的に抽象化している一方で、基盤となる SQLite エンジンには、Postgres と同じように扱うと実行時に問題となる制約があるためです。
優先度別のルールカテゴリー
| 優先度 | カテゴリー | 影響度 | プレフィックス |
|---|---|---|---|
| 1 | スキーマ定義 | 重大 | schema- |
| 2 | マイグレーションと Drizzle Kit | 重大 | migrate- |
| 3 | クエリ構築 | 高 | query- |
| 4 | リレーション | 高 | rel- |
| 5 | トランザクションとバッチ処理 | 中〜高 | tx- |
| 6 | プリペアドステートメントとホットパス | 中〜高 | perf- |
| 7 | 接続とドライバーの設定 | 中 | conn- |
| 8 | 型推論 | 中 | types- |
クイックリファレンス
1. スキーマ定義(重大)
schema-integer-for-booleans— 推論される型が0 | 1ではなくbooleanになるよう、integer({ mode: 'boolean' })を使用しますschema-timestamp-mode-for-dates— 日付はテキストではなく、integer({ mode: 'timestamp_ms' })として保存しますschema-always-primary-key— 隠れた rowid に頼らず、明示的な PK(単一または複合)を宣言しますschema-foreign-keys-with-actions— すべての.references()にonDelete/onUpdateを指定しますschema-index-foreign-keys-and-lookups— 外部キーのカラムと、頻繁に使うWHEREをインデックス化します。SQLite は外部キーに自動でインデックスを作成しませんschema-text-json-not-blob-json—json_extractと JSON パスインデックスが機能するよう、text({ mode: 'json' })を使用しますschema-unique-constraints-for-natural-keys—onConflictの対象を指定できるよう、メールアドレス/slug/externalId には.unique()を使用します
2. マイグレーションと Drizzle Kit(CRITICAL)
migrate-generate-not-push-in-prod—generate + migrateを使用してください。pushは調整できないカラムを削除しますmigrate-explicit-renames— リネームのプロンプトに回答してください。デフォルトではリネームが削除+追加として扱われますmigrate-config-dialect-and-out— フラグなしでコマンドを実行できるようにdrizzle.config.tsを定義してくださいmigrate-apply-with-migrator— 生の SQL ではなく、drizzle-kit migrateまたはドライバーのmigratorモジュールで適用してくださいmigrate-data-backfill-as-custom-sql— DDL とアトミックにバックフィルできるよう、マイグレーション SQL を手動で編集してくださいmigrate-commit-migrations-to-git—drizzle/の SQL とdrizzle/meta/のスナップショットを両方コミットしてください。どちらも必要です
3. クエリの構築(HIGH)
query-select-columns-not-star—db.select({ ... })を使って、必要なカラムだけを取得してくださいquery-avoid-n-plus-one-with-inarray— ループ内のクエリをinArray()に置き換えてくださいquery-always-limit-listings— 一覧取得のクエリにはすべて.limit()(できればカーソルも)が必要ですquery-bind-parameters-not-concat—eq()または SQL テンプレートを使用し、値を文字列連結しないでくださいquery-upsert-with-onconflict— 選択してから書き込むのではなく、.onConflictDoUpdate()でアトミックにアップサートしてくださいquery-returning-instead-of-reselect— 挿入・更新・削除で.returning()を使うと、追加のラウンドトリップを省けますquery-toSQL-and-explain— 負荷の高いパスで、生成された SQL とEXPLAIN QUERY PLANを確認してください
4. リレーション(HIGH)
rel-declare-relations-for-rqb—relations()の宣言により、db.query.*とwithが使えるようになりますrel-prefer-with-over-manual-joins— ネストしたデータの取得にはwithを使用してください。手動の結合では型情報が失われ、コードが増えますrel-partial-columns-in-with—with内のcolumns: { ... }でペイロードを絞り、情報漏えいを防いでくださいrel-filter-with-where-inside-with— 関連行のフィルターは JS ではなくwith.whereに指定してくださいrel-leftjoin-for-flat-aggregates— 集計が必要な場合は、leftJoinとgroupByを使用してください
5. トランザクションとバッチ処理(MEDIUM-HIGH)
tx-wrap-multi-statement-writes— 関連する書き込みをdb.transaction()で囲み、アトミック性とスループットを確保してくださいtx-batch-for-libsql-roundtrips— libsql/Turso/D1 ではdb.batch()を使うと、N 回のラウンドトリップを 1 回にまとめられますtx-no-network-io-inside-transaction— トランザクション内で HTTP/FS/Stripe の呼び出しを await しないでくださいtx-handle-busy-with-retry—SQLITE_BUSYには、リトライ回数を制限して再試行してください。一時的なエラーの場合に限りますtx-single-writer-no-parallel-writes— 書き込みにPromise.allを使うと競合するため、順番に実行してください
6. プリペアドステートメントとホットパス(中〜高)
perf-prepare-hot-paths— リクエストごとに実行されるクエリには、.prepare()とsql.placeholder()を使用しますperf-bulk-insert-multi-row-values— N 回のループによる挿入の代わりに、1 回のvalues([...rows])を使用しますperf-avoid-count-star-on-large-tables—count(*)の代わりに、カウンター行またはキーベースのページネーションを使用しますperf-keyset-not-offset-for-deep-pages— キーベースのページネーションでは、ページをまたいでもコストが一定に保たれますperf-covering-index-for-hot-queries— 射影する列をカバーして、プランナーが行の読み取りを省略できるようにします
7. 接続とドライバーの設定(中)
conn-enable-wal— 並行読み取りと単一の書き込みにはjournal_mode = WALを使用しますconn-set-busy-timeout—busy_timeout = 5000により、競合時に待機するようになりますconn-foreign-keys-pragma— 接続ごとにforeign_keys = ONを設定します。デフォルトではオフですconn-singleton-client— モジュールスコープのシングルトンを使用し、リクエストごとにインスタンスを生成しないでくださいconn-pick-driver-deliberately— 同期、非同期、HTTP のいずれかを、デプロイ先に応じて選択します
8. 型推論(中)
types-infer-select-insert—$inferSelect/$inferInsertで行の型を導出しますtypes-narrow-json-with-dollartype—.$type<Shape>()を使用して、JSON 列のunknownを解消しますtypes-getTableColumns-for-reuse—getTableColumns()とスプレッド構文を使って射影を共有しますtypes-drizzle-zod-for-runtime-validation—createInsertSchema(table)でスキーマから Zod バリデーターを導出しますtypes-bigint-mode-for-large-integers—Number.MAX_SAFE_INTEGERを超える ID にはmode: 'bigint'を使用します
使用方法
references/_sections.md で該当するカテゴリの概要を読み、次に詳細な説明とコード例が記載された個別のルールファイルを読んでください。各ルールには誤った例と正しい例があるため、レビュー対象のコードには正しいパターンを適用します。
複雑な変更(スキーマの再設計、マイグレーション戦略、パフォーマンス改善)を行う場合は、判断する前に該当するカテゴリのルールをすべて読んでください。
- セクションの定義 — カテゴリ構成と影響レベル
- ルールのテンプレート — 新しいルールを追加するためのテンプレート
参照ファイル
| ファイル | 説明 |
|---|---|
| references/_sections.md | カテゴリの定義と順序 |
| assets/templates/_template.md | 新しいルール用のテンプレート |
| metadata.json | バージョンと参照情報 |
関連スキル
effect-ts— アプリケーションが Effect ベースの場合に使用します。Drizzle はEffect.tryPromise経由で統合できます。nextjs-bundle-optimizer— Next.js アプリで SQLite をデータレイヤーとして使用する場合に役立ちます。better-auth— 認証テーブルで Drizzle SQLite とよく併用されます。テーブル生成についてはbetter-auth-scaffoldを参照してください。