Database Migrations
Manage database schema changes with migrations.
Migration Files
migrations/
├── 002_multi_agent.sql
├── 003_agent_auth.sql
├── 004_workflow_executions.sql
├── 005_cloudflare_settings.sql
├── 006_browser_actions_types.sql
└── 007_puppeteer_action_types.sqlInitial Setup
Apply Main Schema
bash
npx wrangler d1 execute agents-dashboard --file=./schema.sqlApply All Migrations
bash
# Apply in order
npx wrangler d1 execute agents-dashboard --file=./migrations/002_multi_agent.sql
npx wrangler d1 execute agents-dashboard --file=./migrations/003_agent_auth.sql
npx wrangler d1 execute agents-dashboard --file=./migrations/004_workflow_executions.sql
npx wrangler d1 execute agents-dashboard --file=./migrations/005_cloudflare_settings.sql
npx wrangler d1 execute agents-dashboard --file=./migrations/006_browser_actions_types.sql
npx wrangler d1 execute agents-dashboard --file=./migrations/007_puppeteer_action_types.sqlLocal Development
bash
# Apply to local database
npx wrangler d1 execute agents-dashboard --local --file=./schema.sql
npx wrangler d1 execute agents-dashboard --local --file=./migrations/002_multi_agent.sql
# ... continue for all migrationsCreating Migrations
1. Create Migration File
bash
touch migrations/008_new_feature.sql2. Write Migration SQL
sql
-- migrations/008_new_feature.sql
-- Add new column
ALTER TABLE agents ADD COLUMN new_field TEXT;
-- Create new table
CREATE TABLE IF NOT EXISTS new_table (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(4)))),
agent_id TEXT NOT NULL REFERENCES agents(id),
data TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Create index
CREATE INDEX IF NOT EXISTS idx_new_table_agent
ON new_table(agent_id);3. Test Locally
bash
npx wrangler d1 execute agents-dashboard --local --file=./migrations/008_new_feature.sql4. Apply to Production
bash
npx wrangler d1 execute agents-dashboard --file=./migrations/008_new_feature.sqlMigration Patterns
Add Column
sql
ALTER TABLE agents ADD COLUMN new_field TEXT;
ALTER TABLE agents ADD COLUMN count INTEGER DEFAULT 0;Add Table
sql
CREATE TABLE IF NOT EXISTS new_table (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(4)))),
name TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);Add Index
sql
CREATE INDEX IF NOT EXISTS idx_table_column ON table_name(column_name);
CREATE INDEX IF NOT EXISTS idx_table_multi ON table_name(col1, col2);Add Foreign Key
SQLite doesn't support ADD CONSTRAINT. Recreate table:
sql
-- Create new table with constraint
CREATE TABLE new_table_temp (
id TEXT PRIMARY KEY,
agent_id TEXT NOT NULL REFERENCES agents(id),
data TEXT
);
-- Copy data
INSERT INTO new_table_temp SELECT * FROM new_table;
-- Drop old table
DROP TABLE new_table;
-- Rename
ALTER TABLE new_table_temp RENAME TO new_table;Add Default Value
sql
ALTER TABLE agents ADD COLUMN status TEXT DEFAULT 'active';Migration Best Practices
1. Always Use IF NOT EXISTS
sql
CREATE TABLE IF NOT EXISTS new_table (...);
CREATE INDEX IF NOT EXISTS idx_name ON table(column);2. Make Migrations Idempotent
Safe to run multiple times:
sql
-- Safe
CREATE TABLE IF NOT EXISTS users (...);
-- Not safe (will fail on re-run)
CREATE TABLE users (...);3. Keep Migrations Small
One feature per migration:
sql
-- migrations/008_add_user_preferences.sql
ALTER TABLE users ADD COLUMN preferences TEXT;4. Name Migrations Descriptively
008_add_user_preferences.sql
009_create_audit_log.sql
010_add_workflow_tags.sql5. Test Before Production
bash
# Test locally first
npx wrangler d1 execute agents-dashboard --local --file=./migrations/008_new.sql
# Verify
npx wrangler d1 execute agents-dashboard --local --command "SELECT * FROM sqlite_master WHERE type='table'"Rollback Strategy
D1 doesn't support transactions for DDL. Create reverse migrations:
Forward Migration
sql
-- migrations/008_add_feature.sql
ALTER TABLE agents ADD COLUMN new_field TEXT;Rollback Migration
sql
-- rollbacks/008_remove_feature.sql
-- Note: SQLite doesn't support DROP COLUMN easily
-- May need to recreate tableSchema Inspection
List Tables
bash
npx wrangler d1 execute agents-dashboard \
--command "SELECT name FROM sqlite_master WHERE type='table'"Describe Table
bash
npx wrangler d1 execute agents-dashboard \
--command "PRAGMA table_info(agents)"List Indexes
bash
npx wrangler d1 execute agents-dashboard \
--command "SELECT name FROM sqlite_master WHERE type='index'"CI/CD Migrations
GitHub Actions
yaml
- name: Apply migrations
run: |
npx wrangler d1 execute agents-dashboard --file=./schema.sql
for f in migrations/*.sql; do
npx wrangler d1 execute agents-dashboard --file="$f"
done
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}Migration Tracking
Consider a migrations table:
sql
CREATE TABLE IF NOT EXISTS _migrations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
);Apply with tracking:
sql
-- At end of migration
INSERT OR IGNORE INTO _migrations (name) VALUES ('008_add_feature');Troubleshooting
Migration Failed
- Check syntax errors
- Verify table/column exists
- Check constraints
bash
# Get error details
npx wrangler d1 execute agents-dashboard --command "SELECT * FROM agents LIMIT 1"Duplicate Column
Error: duplicate column name: new_fieldAlready applied. Skip or check IF NOT EXISTS.
Foreign Key Violation
Error: FOREIGN KEY constraint failedEnsure referenced row exists or set ON DELETE behavior.