flutter moor add initial data after migration

2.3k Views Asked by At

After migrating an entity and adding column, I want to insert value for already existed records in the table for the new added column. How can I do that?

for instance, in this scenario I want dueDate column value to be DateTime(2019,1,1) for records which already existed in the database.

class Todos extends Table {
  IntColumn get id => integer().autoIncrement()();
  TextColumn get title => text().withLength(min: 6, max: 10)();
  TextColumn get content => text().named('body')();
  IntColumn get category => integer().nullable()();
  DateTimeColumn get dueDate => dateTime().nullable()(); // new, added column
}
  int get schemaVersion => 2; // bump because the tables have changed

  @override
  MigrationStrategy get migration => MigrationStrategy(
    onCreate: (Migrator m) {
      return m.createAllTables();
    },
    onUpgrade: (Migrator m, int from, int to) async {
      if (from == 1) {
        // we added the dueDate property in the change from version 1
        await m.addColumn(todos, todos.dueDate);
      }
    }
  );
2

There are 2 best solutions below

0
On

I am not aware of any helper method for this operation but you can use issueCustomQuery() method in the Migrator object.

@override
  MigrationStrategy get migration => MigrationStrategy(
        onCreate: (Migrator m) async { ... }},
        onUpgrade: (Migrator m, int from, int to) async {
           ...   
           final sql = "YOUR CUSTOM SQL"
           await m.issueCustomQuery(sql);  
           ...
          },
      );

If this is the first schema version you can use onCreate callback for initial data creation.

0
On

Await the m.addColumn and .then() you could use customStatement().

onUpgrade: (Migrator m, int from, int to) async {
  if (from == 1) {
    await m.addColumn(todos, todos.dueDate).then((value) async {
        var dateInTheFuture = (new DateTime.utc(2022, 12, 24).millisecondsSinceEpoch / 1000).round();
        await customStatement(''' UPDATE todos SET dueDate = '$dateInTheFuture' ''');
    });
  }
}