简体   繁体   中英

Understanding Migrations in Vapor-Fluent (Server side Swift)

I'm writing a web service in Swift using Vapor framework.

I have model named Item . Intially it has only name and id properties.

typealias VaporModel = Content & PostgreSQLModel & Parameter
final class Item: VaporModel {
    var id: Int?
    var name: String
}

After I configure a controller for the model and add the routes, when I hit the post Item request, I get the error as Model.defaultDatabase is required to use as DatabaseConnectable . I think the error is because I have not added Item to Migrations in configure.swift and I do the same after conforming Item to PostgreSQLMigration .

var migrations = MigrationConfig()
migrations.add(model: Item.self, database: .psql)
services.register(migrations)

Now, I am able to hit the post request and create items in the database.

So I understand that Migration protocol creates the default schema for a model and adds a new table to the database with the model's properties as columns.

Now I want to add a property such as price to my Item class. Now when I hit the post request, I get the error as column "price" of relation "Item" does not exist . I assume the Migration protocol will be able to identify the schema changes and the column to my table (that's what I was used to in while using Realm for my iOS apps). But I am wrong and I read through the Migration docs and implement the prepare and revert methods in migration like below.

extension Item: PostgreSQLMigration {
    static func prepare(on conn: PostgreSQLConnection) -> Future<Void> {
        return Database.create(self, on: conn) { creator in
            creator.field(for: \.price)
        }
    }

    static func revert(on connection: PostgreSQLConnection) -> EventLoopFuture<Void> {
        return Future.map(on: connection) { }
    }
} 

I'm still struck with the same error column "price" of relation "Item" does not exist . What am I missing here? Is my migration code correct?

Also, I understand that if am not making any changes to the Model, I can comment out the migration config, because they need not run every time I run the service. Is that correct?

With your code you haven't added a new migration. You have implemented a manual initial migration, but the initial migration has run already as requested ( migrations.add(model: Item.self, database: .psql) . To create a new migration you would need sth like:

struct ItemAddPriceMigration: Migration {
    typealias Database = PostgreSQLDatabase

    static func prepare(on conn: PostgreSQLConnection) -> EventLoopFuture<Void> {

        return Database.update(Item.self, on: conn) { builder in
            builder.field(for: \.price)
        }
    }

    static func revert(on conn: PostgreSQLConnection) -> EventLoopFuture<Void> {
        return conn.future()
    }
}

And then you need to add it in configure :

migrations.add(migration: ItemAddPriceMigration.self, database: .psql)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM