Databasemigratie

Finch heeft een ingebouwd migratiesysteem dat schemawijzigingen in de loop van de tijd beheert.

Migratie-commando's

Commando Beschrijving
finch migrate --init Alle openstaande migraties uitvoeren
finch migrate --create --name <name> Nieuw migratiebestand aanmaken
finch migrate --rollback Laatste migratie terugdraaien
finch migrate --list Status van alle migraties weergeven
finch migrate --init --sqlite Uitvoeren voor SQLite
finch migrate --create --name <name> --sqlite Aanmaken voor SQLite

Migratiebestandsstructuur

Migraties bevinden zich in ./migrations/ (MySQL) of ./migrations_sqlite/ (SQLite):

-- NEW VERSION
CREATE TABLE articles (
    id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(255) NOT NULL,
    body TEXT,
    published TINYINT(1) DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- ROLL BACK
DROP TABLE IF EXISTS articles;

Elk migratiebestand moet zowel een -- NEW VERSION-sectie (voor toepassing) als een -- ROLL BACK-sectie (voor terugdraaien) bevatten.

Elke migratie (bestand- of Dart-gebaseerd) wordt uitgevoerd binnen een databasetransactie: als een instructie mislukt, wordt de transactie automatisch teruggedraaid en wordt de migratie niet als toegepast gemarkeerd.

Dart-gebaseerde migraties

In plaats van SQL-bestanden kun je migraties in Dart definiëren door DartMigration te extenden. Bouw de SQL voor up()/down() met addSql(), en stel target in om MigrationTarget.mysql of MigrationTarget.sqlite te kiezen:

import 'package:finch/mysql.dart';

class M1CreateUsers extends DartMigration {
  @override
  MigrationTarget get target => MigrationTarget.sqlite;

  M1CreateUsers() : super('m1_create_users');

  @override
  void up() {
    addSql('''
      CREATE TABLE users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT,
        email TEXT
      );
    ''');
  }

  @override
  void down() {
    addSql('DROP TABLE IF EXISTS users;');
  }
}

Registreer migraties op de FinchApp-instantie. De naam die aan super(...) wordt doorgegeven, moet uniek zijn onder alle geregistreerde migraties:

final app = FinchApp(configs: configs)
  ..registerDartMigration([
    M1CreateUsers(),
    M2InsertUsers(),
  ]);

Eenmaal geregistreerd, voeren migrate --init, --rollback en --list (en hun --sqlite / migrate_sqlite-equivalenten) de Dart-migraties uit die overeenkomen met dat target, in plaats van migratiebestanden te lezen.

Bestandsnaming

Migratiebestanden worden benoemd met een tijdstempel:

2024_01_15_143022_create_articles_table.sql

Automatisch uitvoeren bij opstarten

Je kunt migraties automatisch laten uitvoeren bij het opstarten van de applicatie:

FinchConfigs(
  autoMigrate: true,
)

Waarschuwing: Gebruik deze optie met voorzichtigheid in productie.

Voorbeeldworkflow

# Migratie aanmaken voor een nieuwe tabel
finch migrate --create --name create_products_table

# Bewerk het aangemaakte bestand in migrations/
# Voer daarna de migratie uit
finch migrate --init

# Als terugdraaien nodig is
finch migrate --rollback