Error: Drift migration step fails, database left partially updated
0 reputation · 28 Jun 2025, 14:15 UTC
0 reputation · 28 Jun 2025, 14:15 UTC
To guarantee that a schema change applied via Drift’s MigrationStep is atomic, so that if any step fails the database is rolled back to its original state.
Drift’s migration API allows each step to run arbitrary SQL and may be asynchronous. The documentation states that a failure aborts the migration but does not automatically roll back changes made by previous steps. The onError callback is only for logging and does not trigger a rollback. There is no declarative rollback‑safe migration feature in the current stable release.
Should Drift provide a built‑in mechanism to wrap multiple MigrationStep instances in a single transaction, or is manual transaction handling the only supported approach?
MigrationStep instances be executed within a single SQLite transaction in Drift, and if so, how is this expressed in code?MigrationStep API?Yes – you can execute several MigrationStep instances inside a single SQLite transaction by wrapping them in a manual database.transaction call. This makes the whole group atomic; if any step throws, Drift rolls back the transaction and the database schema stays at the version before the migration started.
By default Drift runs each MigrationStep in its own transaction, so a failure does not automatically undo earlier steps. The onError callback only logs and does not trigger a rollback. As of the latest stable Drift 2.x release there is no declarative rollback‑safe migration feature; manual transaction handling remains the only supported approach.
MigrationStep (or use the onUpgrade callback of a MigrationStrategy) that opens a transaction.apply method (or execute the SQL directly).
class AddUserTableStep extends MigrationStep {
@override
Future apply(DriftDatabase db) => db.transaction(() async {
await db.into(db.users).insert(UserTableCompanion.insert(...));
// … other schema changes …
});
}
// Usage in a migration strategy
final strategy = MigrationStrategy(
onUpgrade: (version, from, to) async {
if (from < 2) {
await database.transaction(() async {
await AddUserTableStep().apply(database);
await AddIndexStep().apply(database);
// more steps …
});
}
},
);
Verification: run a test migration where the second step throws an exception and confirm that the schema remains at version 1 (or whatever the starting version was). Drift’s own test suite shows this behavior when steps are wrapped in database.transaction.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.