Database Operations
Database Operations
Section titled “Database Operations”PulseStream uses two PostgreSQL databases:
- CP database — Control Plane (organizations, users, workspaces, billing)
- Agent database — API Server (incidents, analyses, telemetry)
Migrations
Section titled “Migrations”Check Current State
Section titled “Check Current State”# CP databasekubectl exec -n <namespace> deployment/control-plane -- \ uv run alembic -c migrations/alembic.ini current
# Agent databasekubectl exec -n <namespace> deployment/api-server -- \ uv run alembic -c migrations/alembic.ini currentCreate a New Migration
Section titled “Create a New Migration”# From service root directorycd control-plane # or api-serveralembic -c migrations/alembic.ini revision --autogenerate -m "short_description"Apply Migrations (Kubernetes)
Section titled “Apply Migrations (Kubernetes)”Init containers handle migrations automatically on pod restart:
kubectl rollout restart deployment/<service> -n <namespace>Local Database Reset (Tilt)
Section titled “Local Database Reset (Tilt)”Wipe all data and re-run migrations:
bash scripts/tilt-reset-db.shThis drops CP (port 5433) and Agent (port 5434) databases, restarts deployments, and re-runs migrations.
Schema Drift Detection
Section titled “Schema Drift Detection”Schema drift tests catch model changes without migrations at PR time — no DB needed:
make test-cp-unit # includes schema drift checkmake test-api-pr-gate # includes schema drift checkSkip with SKIP_SCHEMA_DRIFT_CHECK=1 for comment-only edits.
Emergency: Stuck Migration
Section titled “Emergency: Stuck Migration”If a migration fails partway:
- Check
alembic_versiontable for current revision - Do not manually modify the migration file
- Create a new migration that fixes the issue
- If the database is in an inconsistent state, restore from backup
Key Gotcha
Section titled “Key Gotcha”The async env.py must use .begin(), not .connect(). Using .connect() opens an implicit transaction that silently rolls back — migrations appear to succeed but nothing is committed.