DatabaseMigrator
DatabaseMigrator is responsible for managing and executing database schema migrations.
It provides an ordered, traceable, and repeatable mechanism to evolve database schemas safely as an application grows.
In the Scripting SQLite API, DatabaseMigrator is typically used together with DatabaseQueue or DatabasePool, and migrations are executed during database initialization or application startup.
Design Goals
The core goals of DatabaseMigrator are:
- Manage migrations using explicit identifiers
- Guarantee that each migration runs at most once
- Execute migrations in registration order
- Provide safe access to
Databaseduring migrations - Support foreign key checking strategies for complex schema changes
- Expose migration state for diagnostics and debugging
Type Definition
Basic Workflow
A typical migration workflow consists of:
- Creating a
DatabaseMigrator - Registering migrations in order
- Executing migrations during database setup
Migration Identifiers
Each migration must have a unique identifier, which is used to:
- Track whether the migration has been applied
- Determine execution order
- Prevent duplicate execution
Migrations are executed in registration order, not by sorting identifiers.
Recommendations
- Identifiers should be stable and never changed after release
- Use descriptive, human-readable names
- Do not remove or reuse published migration identifiers
registerMigration
Basic Registration
The migration callback receives a writable Database instance.
Registration with Foreign Key Checks
Foreign Key Check Strategies
DatabaseMigratorForeignKeyChecks
Controls when foreign key constraints are validated during a migration.
deferred
- Foreign keys are validated at transaction commit
- Suitable for complex migrations involving multiple tables
immediate
- Foreign keys are validated immediately after each statement
- Suitable for simple, well-ordered migrations
disablingDeferredForeignKeyChecks
Disables deferred foreign key checking during migrations.
Use cases:
- The platform does not support deferred foreign keys
- The migration logic does not rely on foreign key enforcement
- You want errors to surface as early as possible
migrate
Executes registered migrations.
Or migrate only up to a specific migration:
Notes:
- Migrations are executed using the writer side of
DatabaseQueueorDatabasePool - Each migration runs inside a transaction
- Already applied migrations are skipped automatically
eraseDatabaseOnSchemaChange
Controls whether the database should be erased and rebuilt if an incompatible schema change is detected.
Guidelines:
- Appropriate for cache or ephemeral databases
- Not recommended for critical user data
- Enabling this option may result in complete data loss
Migration State Inspection
migrations
Returns all registered migration identifiers.
appliedMigrations / appliedIdentifiers
Returns the migrations that have been applied to the database.
completedMigrations
Returns the list of migrations that completed successfully.
hasCompletedMigrations
Indicates whether all registered migrations have been applied.
hasBeenSuperseded
Indicates whether the database schema has been superseded by newer migration definitions.
This typically means:
- Migration definitions have changed
- The database schema no longer matches the current code
Best Practices and Notes
- Migration functions should focus on schema changes only
- Avoid large data writes inside migrations
- Never modify or remove published migrations
- Use
eraseDatabaseOnSchemaChangewith extreme caution - Keep migrations deterministic and repeatable
Summary
DatabaseMigrator provides a reliable, controlled, and inspectable migration system:
- Identifier-based ordered migrations
- Built-in transaction and foreign key handling
- Detailed migration state inspection
- Seamless integration with Queue and Pool
