mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-03-21 18:11:27 -07:00
update skills
This commit is contained in:
188
.agents/skills/cloudflare-deploy/references/d1/configuration.md
Normal file
188
.agents/skills/cloudflare-deploy/references/d1/configuration.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# D1 Configuration
|
||||
|
||||
## wrangler.jsonc Setup
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"name": "your-worker-name",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2025-01-01", // Use current date for new projects
|
||||
"d1_databases": [
|
||||
{
|
||||
"binding": "DB", // Env variable name
|
||||
"database_name": "your-db-name", // Human-readable name
|
||||
"database_id": "your-database-id", // UUID from dashboard/CLI
|
||||
"migrations_dir": "migrations" // Optional: default is "migrations"
|
||||
},
|
||||
// Read replica (paid plans only)
|
||||
{
|
||||
"binding": "DB_REPLICA",
|
||||
"database_name": "your-db-name",
|
||||
"database_id": "your-database-id" // Same ID, different binding
|
||||
},
|
||||
// Multiple databases
|
||||
{
|
||||
"binding": "ANALYTICS_DB",
|
||||
"database_name": "analytics-db",
|
||||
"database_id": "yyy-yyy-yyy"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## TypeScript Types
|
||||
|
||||
```typescript
|
||||
interface Env { DB: D1Database; ANALYTICS_DB?: D1Database; }
|
||||
|
||||
export default {
|
||||
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
|
||||
const result = await env.DB.prepare('SELECT * FROM users').all();
|
||||
return Response.json(result.results);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Migrations
|
||||
|
||||
File structure: `migrations/0001_initial_schema.sql`, `0002_add_posts.sql`, etc.
|
||||
|
||||
### Example Migration
|
||||
|
||||
```sql
|
||||
-- migrations/0001_initial_schema.sql
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
email TEXT UNIQUE NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_users_email ON users(email);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS posts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
content TEXT,
|
||||
published BOOLEAN DEFAULT 0,
|
||||
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX idx_posts_user_id ON posts(user_id);
|
||||
CREATE INDEX idx_posts_published ON posts(published);
|
||||
```
|
||||
|
||||
### Running Migrations
|
||||
|
||||
```bash
|
||||
# Create new migration file
|
||||
wrangler d1 migrations create <db-name> add_users_table
|
||||
# Creates: migrations/0001_add_users_table.sql
|
||||
|
||||
# Apply migrations
|
||||
wrangler d1 migrations apply <db-name> --local # Apply to local DB
|
||||
wrangler d1 migrations apply <db-name> --remote # Apply to production DB
|
||||
|
||||
# List applied migrations
|
||||
wrangler d1 migrations list <db-name> --remote
|
||||
|
||||
# Direct SQL execution (bypasses migration tracking)
|
||||
wrangler d1 execute <db-name> --remote --command="SELECT * FROM users"
|
||||
wrangler d1 execute <db-name> --local --file=./schema.sql
|
||||
```
|
||||
|
||||
**Migration tracking**: Wrangler creates `d1_migrations` table automatically to track applied migrations
|
||||
|
||||
## Indexing Strategy
|
||||
|
||||
```sql
|
||||
-- Index frequently queried columns
|
||||
CREATE INDEX idx_users_email ON users(email);
|
||||
|
||||
-- Composite indexes for multi-column queries
|
||||
CREATE INDEX idx_posts_user_published ON posts(user_id, published);
|
||||
|
||||
-- Covering indexes (include queried columns)
|
||||
CREATE INDEX idx_users_email_name ON users(email, name);
|
||||
|
||||
-- Partial indexes for filtered queries
|
||||
CREATE INDEX idx_active_users ON users(email) WHERE active = 1;
|
||||
|
||||
-- Check if query uses index
|
||||
EXPLAIN QUERY PLAN SELECT * FROM users WHERE email = ?;
|
||||
```
|
||||
|
||||
## Drizzle ORM
|
||||
|
||||
```typescript
|
||||
// drizzle.config.ts
|
||||
export default {
|
||||
schema: './src/schema.ts', out: './migrations', dialect: 'sqlite', driver: 'd1-http',
|
||||
dbCredentials: { accountId: process.env.CLOUDFLARE_ACCOUNT_ID!, databaseId: process.env.D1_DATABASE_ID!, token: process.env.CLOUDFLARE_API_TOKEN! }
|
||||
} satisfies Config;
|
||||
|
||||
// schema.ts
|
||||
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
|
||||
export const users = sqliteTable('users', {
|
||||
id: integer('id').primaryKey({ autoIncrement: true }),
|
||||
email: text('email').notNull().unique(),
|
||||
name: text('name').notNull()
|
||||
});
|
||||
|
||||
// worker.ts
|
||||
import { drizzle } from 'drizzle-orm/d1';
|
||||
import { users } from './schema';
|
||||
export default {
|
||||
async fetch(request: Request, env: Env) {
|
||||
const db = drizzle(env.DB);
|
||||
return Response.json(await db.select().from(users));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Import & Export
|
||||
|
||||
```bash
|
||||
# Export full database (schema + data)
|
||||
wrangler d1 export <db-name> --remote --output=./backup.sql
|
||||
|
||||
# Export data only (no schema)
|
||||
wrangler d1 export <db-name> --remote --no-schema --output=./data-only.sql
|
||||
|
||||
# Export with foreign key constraints preserved
|
||||
# (Default: foreign keys are disabled during export for import compatibility)
|
||||
|
||||
# Import SQL file
|
||||
wrangler d1 execute <db-name> --remote --file=./backup.sql
|
||||
|
||||
# Limitations
|
||||
# - BLOB data may not export correctly (use R2 for binary files)
|
||||
# - Very large exports (>1GB) may timeout (split into chunks)
|
||||
# - Import is NOT atomic (use batch() for transactional imports in Workers)
|
||||
```
|
||||
|
||||
## Plan Tiers
|
||||
|
||||
| Feature | Free | Paid |
|
||||
|---------|------|------|
|
||||
| Database size | 500 MB | 10 GB |
|
||||
| Batch size | 1,000 statements | 10,000 statements |
|
||||
| Time Travel | 7 days | 30 days |
|
||||
| Read replicas | ❌ | ✅ |
|
||||
| Sessions API | ❌ | ✅ (up to 15 min) |
|
||||
| Pricing | Free | $5/mo + usage |
|
||||
|
||||
**Usage pricing** (paid plans): $0.001 per 1K reads + $1 per 1M writes + $0.75/GB storage/month
|
||||
|
||||
## Local Development
|
||||
|
||||
```bash
|
||||
wrangler dev --persist-to=./.wrangler/state # Persist across restarts
|
||||
# Local DB: .wrangler/state/v3/d1/<database-id>.sqlite
|
||||
sqlite3 .wrangler/state/v3/d1/<database-id>.sqlite # Inspect
|
||||
|
||||
# Local dev uses free tier limits by default
|
||||
```
|
||||
Reference in New Issue
Block a user