Important: ElizaOS 1.0 introduces a powerful dynamic migration system that automatically manages database schema changes for plugins. This guide will help you understand how it works and how to use it effectively.
What are Dynamic Migrations?
Dynamic migrations in ElizaOS are an automated system for managing database schema changes without manual intervention. Unlike traditional migration systems that require pre-generated SQL files, ElizaOS generates and executes migrations at runtime based on your plugin’s Drizzle schema definitions.Key Features
- Automatic Schema Detection: Detects changes between your code and database
- Safe by Default: Blocks destructive migrations unless explicitly allowed
- Plugin Isolation: Each plugin’s tables are isolated in their own schema
- Concurrent Safety: Uses advisory locks to prevent race conditions
- Full Audit Trail: Tracks all migrations with snapshots and journal entries
How Dynamic Migrations Work
Architecture Overview
Migration Process
- Schema Discovery: When your plugin loads, the system discovers schema definitions
- Snapshot Generation: Creates a snapshot of your current schema structure
- Comparison: Compares with the last known database state
- Diff Calculation: Determines what SQL operations are needed
- Safety Check: Analyzes for potential data loss (dropped tables/columns)
- Execution: Applies changes in a transaction with full rollback capability
- Recording: Stores migration history, snapshots, and journal entries
Database Tables
The migration system creates these tables to track state:Adding Dynamic Migrations to Your Plugin
Step 1: Define Your Schema
Create your Drizzle schema definition in your plugin:Step 2: Register Schema with Plugin
Include the schema in your plugin definition:Step 3: Schema Isolation
For better isolation and to avoid conflicts:- Core Plugin (
@elizaos/plugin-sql
): Uses thepublic
schema - All Other Plugins: Should use namespaced schemas like
plugin_<name>
Development vs Production Behavior
The migration system behaves differently based on your environment:Development Environment
In development (NODE_ENV !== 'production'
):
- Verbose Logging: Detailed migration output by default
- Destructive Operations: More permissive (with warnings)
- Advisory Locks: Skipped for PGLite/memory databases
- Quick Iteration: Optimized for rapid schema changes
Production Environment
In production (NODE_ENV === 'production'
):
- Minimal Logging: Only essential information logged
- Destructive Operations: Blocked by default for safety
- Advisory Locks: Full concurrency protection
- Safety First: Requires explicit confirmation for risky operations
Configuration and Overrides
Environment Variables
Control migration behavior through environment variables:Programmatic Options
When calling migrations programmatically:Migration Options Reference
Option | Type | Default | Description |
---|---|---|---|
verbose | boolean | true in dev, false in prod | Show detailed SQL statements |
force | boolean | false | Allow destructive migrations |
dryRun | boolean | false | Preview changes without applying |
allowDataLoss | boolean | false | Alternative to force |
Handling Schema Changes
Safe Changes (Always Allowed)
These changes are always safe and will execute automatically:Destructive Changes (Require Confirmation)
These changes will be blocked unless explicitly allowed:Handling Destructive Changes
When you need to make destructive changes:Option 1: Environment Variable (Recommended for CI/CD)
Option 2: Migration Options (Recommended for Scripts)
Option 3: Manual Migration (Recommended for Production)
For complex production migrations, consider using Drizzle Kit:Advanced Usage
Checking Migrations Without Executing
Preview what changes would be made:Migration Status and History
Query migration status for debugging:Resetting Migrations (Development Only)
For development environments, you can reset migration history:Best Practices
1. Schema Naming Conventions
2. Version Control
3. Testing Migrations
4. Production Safety
5. Gradual Migration Strategy
For complex schema changes:Troubleshooting
Common Issues and Solutions
Issue: “Destructive migration blocked”
Solution: SetELIZA_ALLOW_DESTRUCTIVE_MIGRATIONS=true
or use force: true
Issue: “Migration already in progress”
Solution: The system uses advisory locks. Wait for the other migration to complete.Issue: “No changes detected” but schema is different
Solution: Check if migrations were already applied. UsegetStatus()
to verify.
Issue: PGLite not creating schemas
Solution: PGLite may not support all PostgreSQL features. Use PostgreSQL for production.Debug Mode
Enable detailed logging for troubleshooting:Migration System Internals
Advisory Locks
For PostgreSQL databases, the system uses advisory locks to prevent concurrent migrations:Transaction Safety
All migrations run in transactions:- BEGIN - Start transaction
- Execute SQL - Apply schema changes
- Record Migration - Update tracking tables
- COMMIT or ROLLBACK - Based on success
Schema Transformation
The system automatically handles schema namespacing:Conclusion
Dynamic migrations in ElizaOS provide a powerful, safe way to manage database schema evolution. By following the practices in this guide, you can:- Safely evolve your plugin’s database schema
- Maintain consistency across environments
- Prevent accidental data loss
- Keep a complete audit trail