Database / ORM Overview
Migrations
Migrations are somewhat like version control for your database, allowing an application team to easily modify and share the application's database schema.
In Archery, every Model defines its own storage schema. This ensures your code is exactly synchronized with the underlying datastore architecture at all times.
Defining Your Schema
When establishing a new feature, you construct a new Model. Inside of your new model, simply define the appropriate database columns as a static property:
class Flight extends Model {
String name;
String destination;
Flight({required this.name, required this.destination});
static const Map<String, String> columnDefinitions = {
'name': 'TEXT NOT NULL',
'destination': 'TEXT NOT NULL',
};
@override
Map<String, dynamic> toJson() => {
'name': name,
'destination': destination,
};
}
The Archery ORM leverages these columnDefinitions when you issue a migration. The framework automatically prepends standard primary keys and timestamps.
Running Migrations
Archery's Migration Providers execute your schema instructions asynchronously during the application's boot sequence.
For example, to ensure your new Flight model is properly instantiated in a local sqlite database before the application begins accepting HTTP requests, register it within the SqliteMigrationsProvider:
class SqliteMigrationsProvider extends Provider {
@override
Future<void> boot(ServiceContainer container) async {
// Register the new Flight model migration
await SQLiteModel.migrate<Flight>(
constructor: Flight.fromJson,
columnDefinitions: Flight.columnDefinitions,
);
}
}
When you eventually run App().boot(), Archery iterates through your Migration Providers and performs standard CREATE TABLE IF NOT EXISTS commands against your active databases.