Schema & Migrations
Aerostack uses a numbered migration file system. Migrations run in order and are tracked to prevent re-runs.
Create a migration
Section titled “Create a migration”aerostack db migrate new add_posts_tableWrite the migration
Section titled “Write the migration”-- migrations/0001_add_posts_table.sqlCREATE TABLE IF NOT EXISTS posts ( id TEXT PRIMARY KEY, user_id TEXT NOT NULL, title TEXT NOT NULL, body TEXT, published INTEGER DEFAULT 0, created_at INTEGER NOT NULL, updated_at INTEGER, FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE);
CREATE INDEX IF NOT EXISTS idx_posts_user_id ON posts(user_id);CREATE INDEX IF NOT EXISTS idx_posts_created_at ON posts(created_at);Apply migrations
Section titled “Apply migrations”# Local developmentaerostack db migrate apply
# Stagingaerostack db migrate apply --remote staging
# Productionaerostack db migrate apply --remote productionCheck migration status
Section titled “Check migration status”aerostack db migrate apply --dry-runCommon column patterns
Section titled “Common column patterns”-- Auto-ID with UUID (Workers-compatible)id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
-- Timestamps (Unix ms)created_at INTEGER NOT NULL DEFAULT (unixepoch() * 1000),updated_at INTEGER,
-- Soft deletedeleted_at INTEGER,
-- JSON metadatametadata TEXT DEFAULT '{}',
-- Boolean (SQLite has no boolean type)is_active INTEGER DEFAULT 1,Run schema queries from SDK
Section titled “Run schema queries from SDK”// Get all table namesconst { results } = await sdk.db.query( "SELECT name FROM sqlite_master WHERE type = 'table' AND name NOT LIKE 'sqlite_%'")
// Column infoconst { results: cols } = await sdk.db.query( `PRAGMA table_info(posts)`)