Generic Migrations in Fluent

So we pre-populated our database with initial data in previous two tips and even added related data. That’s fine, but it is all related to #postgresql.

What if we wanted to make it work with all the databases that Vapor supports.

Well in that case we need a Generic Migration.

import Async
import Fluent
import Foundation

public final class TestModel<D>: Model where D: QuerySupporting {

  public typealias Database = D
  public typealias ID = Int
  public static var idKey: IDKey { return \.id }
  public static var entity: String {
    return "testModel"
  public static var database: DatabaseIdentifier<D> {
    return .init("test")
  var id: Int?
  var name: String
  var num : Int
  init(name: String, num: Int) { = name
    self.num = num

extension TestModel: Migration where D: SchemaSupporting, D: QuerySupporting { }

extension MigrationConfig {
  public mutating func addTestModels<D>(for database: DatabaseIdentifier<D>)
    where D: QuerySupporting, D: IndexSupporting {
      self.add(model: TestModel<D>.self, database: database)

let testNames = [

internal struct TestModelMigration<D>: Migration where D: QuerySupporting & SchemaSupporting {
  typealias Database = D
  static func prepare(on connection: Database.Connection) -> Future<Void> {
    //Insert all names
    let futures : [EventLoopFuture<Void>] = { name in
      return TestModel<D>(name: name, num: 1).create(on: connection).map(to: Void.self) { _ in return }
    return Future<Void>.andAll(futures, eventLoop: connection.eventLoop)
  static func revert(on connection: Database.Connection) -> Future<Void> {
    do {
      // Delete all names
      let futures = try { name in
        return try TestModel<D>.query(on: connection).filter(\, .equals, .data(name)).delete()
      return Future<Void>.andAll(futures, eventLoop: connection.eventLoop)
    catch {
      return connection.eventLoop.newFailedFuture(error: error)


Run your migration

In configure.swift add the code:

migrations.add(model: TestModel<PostgreSQLDatabase>.self, database: .psql)
migrations.add(migration: TestModelMigration<PostgreSQLDatabase>.self, database: .psql)

And the data is added:

Prev: Pre-populating Related Tables in Vapor

Next: Generic Pre-populated Models in Fluent

Vapor 3 Tutorial Start

#tutorial #fluent #vapor #model #migration #db #generic #pub #pre-populate