Flutter

Cara untuk melakukan migration pada SQFLite

SQFLite adalah penyimpanan lokal berupa table yang sering digunakan pada project Flutter. Setiap pengembangan aplikasi, tak jarang kita memukan kondisi, di mana...

Ikhwan Written by Ikhwan · 2 min read >

SQFLite adalah penyimpanan lokal berupa table yang sering digunakan pada project Flutter. Setiap pengembangan aplikasi, tak jarang kita memukan kondisi, di mana kita harus menambahkan table baru pada atau mengubah column pada table yang sebelumnya telah digunakan. Pada kondisi tersebut dibutuhkan lah migration.

Tulisan ini termasuk ke pada rangkaian pembahasan penyimpanan data lokal pada Flutter:

  1. Penyimpanan data lokal pada Flutter (shared_preferences)
  2. Penyimpanan data lokal pada Flutter (sqflite)
  3. [Tulisan ini] Update schema pada SQFLite

Why?

Migration harus dilakukan, karena jika tidak dilakukan akan terjadi error ketika device yang telah pernah menginstall aplikasi, melakukan pembaruan. Sedangkan untuk device yang baru pertama kali menginstall aplikasi, error mungkin tidak akan terjadi.

Schema

Pada tulisan sebelumnya kita telah memiliki satu table, yaitu table mahasiswa. Kali ini kita akan menambahkan column baru pada table tersebut, dan juga membuat table baru. Berikut schemanya:

Yuk Ngoding

Sesuai dengan schema sebelumnya, kita akan menambahkan column baru di table Student dan juga membuat satu table baru. Langkah pertama, kita tambahkan propery baru di class Student, seperti berikut:

import '../commons/const.dart';

class StudentModel {
  String id;
  String name;
  String department;
  int sks;
  String? address;

  StudentModel({
    required this.id,
    required this.name,
    required this.department,
    required this.sks,
    this.address,
  });

  // Convert  into a Map. The keys must correspond to the names of the
  // columns in the database.
  Map<String, dynamic> toMap() {
    return {
      Constant.studentId: id,
      Constant.studentName: name,
      Constant.studentDepartment: department,
      Constant.studentSKS: sks,
      Constant.studentAddress: address,
    };
  }

  // Implement toString to make it easier to see information about
  // each student when using the print statement.
  @override
  String toString() {
    return 'Student{${Constant.studentId}: $id, ${Constant.studentName}: $name, '
        '${Constant.studentDepartment}: $department, '
        '${Constant.studentSKS}: $sks, ${Constant.studentAddress}: $address}';
  }
}

Setelah itu kita buat class Organization untuk table baru nantinya.

import '../commons/const.dart';

class OrganizationModel {
  String id;
  String name;

  OrganizationModel({
    required this.id,
    required this.name,
  });

  // Convert  into a Map. The keys must correspond to the names of the
  // columns in the database.
  Map<String, dynamic> toMap() {
    return {
      Constant.organizationId: id,
      Constant.organizationName: name,
    };
  }

  // Implement toString to make it easier to see information about
  // each student when using the print statement.
  @override
  String toString() {
    return 'Organization{${Constant.studentId}: $id, '
        '${Constant.studentName}: $name}';
  }
}

Setelah memperbarui model, kita lanjut perbarui class Constant untuk nama column-column baru.

class Constant {
  static const studentId = 'id';
  static const studentName = 'name';
  static const studentDepartment = 'department';
  static const studentSKS = 'sks';
  static const studentAddress = 'address';

  static const organizationId = 'id';
  static const organizationName = 'name';
}

Pada code pada MySQFLite.dart di tulisan sebelumnya menjadi seperti berikut:

class MySqflite {

  ...

  static final _databaseV1 = 1;
  static final _databaseV2 = 2;

  static const tableStudent = 'Student';
  static const tableOrganization = 'Organization'; // new Table

  ...

  _initDatabase() async {
    var databasesPath = await getDatabasesPath();
    String path = join(databasesPath, _databaseName);

    return await openDatabase(path, version: _databaseV2,
        onCreate: (db, version) async {
      var batch = db.batch();
      _onCreateTableStudentV2(batch);
      _onCreateTableOrganizationV2(batch);
      await batch.commit();
    }, onUpgrade: (db, oldVersion, newVersion) async {
      var batch = db.batch();
      if (oldVersion == _databaseV1) {
        _onUpdateTableStudentV1ToV2(batch);
        _onCreateTableOrganizationV2(batch);
      }
      await batch.commit();
    });
  }

  void _onCreateTableStudentV2(Batch batch) async {
    batch.execute('''
          CREATE TABLE $tableStudent (
            ${Constant.studentId} TEXT PRIMARY KEY,
            ${Constant.studentName} TEXT,
            ${Constant.studentDepartment} TEXT,
            ${Constant.studentSKS} INTEGER,
            ${Constant.studentAddress} TEXT
          )
          ''');
  }

  void _onUpdateTableStudentV1ToV2(Batch batch) async {
    batch.execute(
        '''ALTER TABLE $tableStudent ADD COLUMN ${Constant.studentAddress} TEXT''');
  }

  void _onCreateTableOrganizationV2(Batch batch) async {
    batch.execute('''
          CREATE TABLE $tableOrganization (
            ${Constant.organizationName} TEXT,
            ${Constant.organizationId} TEXT
          )
          ''');
  }

  ...

}
  • Pada function _initDatabase() kita menaikkan versi database menjadi _databaseV2.
  • Pada bagian onCreate database, kita menjalankan function untuk membuat 2 table sesuai dengan schema baru yang kita miliki
  • Sedangkan untuk onUpgrade kita melakukan pengecekan versi, melakukan alter untuk perubahan schema pada table mahasiswa, dan membuat table baru untuk table organisasi.
  • Setelah melakukan onUpgrade (migration), kita bisa mengoperasikan database, seperti menambah data, mengambil data, tanpa menemukan error terkait version atau schema yang kita gunakan.

Hasil

Untuk melihat keseluruhan codenya (termasuk 2 part sebelumnya), temen” bisa mengunjungi github ya.

Berikut merupakan hasil dari memasukkan data sebelum migration dilakukan, dan memasukkan data setelah migration dilakukan.

Untuk data sebelum migration, address akan bernilai null. Oleh karena itu disini kita tampilkan tulisan Empty.

Sekian tulisan kali ini, terimakasih dan semoga bermanfaat ya 😀. Tulisan ini termasuk ke pada rangkaian pembahasan penyimpanan data lokal pada Flutter:

  1. Penyimpanan data lokal pada Flutter (shared_preferences)
  2. Penyimpanan data lokal pada Flutter (sqflite)
  3. [Tulisan ini] Update schema pada SQFLite

Oh iya di website ini ada tulisan menarik lainnya juga loh, seperti berikut:

yukngoding_id_webViewFlutter

Menggunakan WebView di Flutter

Ikhwan in Flutter
  ·   2 min read

Tinggalkan Balasan

Alamat email Anda tidak akan dipublikasikan. Ruas yang wajib ditandai *