-
Notifications
You must be signed in to change notification settings - Fork 438
Description
Describe the bug
The Migration.renameColumn and Migration.renameTable methods in Drift generate SQL statements that are not idempotent. When the same migration is executed multiple times, it fails because the SQL statements do not check whether the column or table has already been renamed.
Environment
- Drift Version:
- drift: ^2.28.1
- drift_dev: ^2.27.0
- Dart Version: 3.9.2
- Flutter Version: 3.35.5
- Database: SQLite
Description
When using Migration.renameColumn or Migration.renameTable in a migration step, the generated SQL statements (e.g., ALTER TABLE ... RENAME COLUMN ... or ALTER TABLE ... RENAME TO ...) do not include existence checks. This means:
- If a migration is applied successfully once, attempting to apply it again will fail
- The migration cannot be safely re-run in case of partial failures or rollbacks
- This violates the principle of idempotency, which is crucial for reliable database migrations
Steps to Reproduce
- Create a migration that uses
Migration.renameColumn:
from3To4: (m, schema) async {
await m.renameColumn(
schema.notebookMemoRecords,
'leaf_id',
schema.notebookMemoRecords.pageId,
);
// before run other steps, some time app killed by OS on mobile device
// other steps ...
}- Apply the migration to a database (schema version 3 → 4)
- Attempt to apply the same migration again (e.g., by resetting the schema version or re-running the migration)
Expected Behavior
The migration should be idempotent. If the column or table has already been renamed, the migration should either:
- Skip the rename operation silently, or
- Check for the existence of the target name before attempting the rename
This would allow the migration to be safely applied multiple times without errors.
Actual Behavior
When the migration is executed a second time, SQLite throws an error because:
- For
renameColumn: The source column no longer exists (it was already renamed) - For
renameTable: The source table no longer exists (it was already renamed)