1

我正在使用 Vapor 框架在 Swift 中编写 Web 服务。

我有模型命名Item。最初它只有 name 和 id 属性。

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

在我为模型配置控制器并添加路由后,当我点击 post Item 请求时,我得到的错误为Model.defaultDatabase is required to use as DatabaseConnectable. 我认为错误是因为我没有添加ItemMigrationsin并且在configure.swift符合.ItemPostgreSQLMigration

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

现在,我可以点击发布请求并在数据库中创建项目。

因此,我了解该Migration协议为模型创建了默认架构,并将新表添加到数据库中,并将模型的属性作为列。

现在我想向price我的 Item 类添加一个属性。现在,当我点击发布请求时,我得到的错误为column "price" of relation "Item" does not exist. 我假设迁移协议将能够识别架构更改和我的表的列(这是我在 iOS 应用程序中使用 Realm 时所习惯的)。但是我错了,我通读了迁移文档并在迁移中实现了preparerevert方法,如下所示。

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) { }
    }
} 

我仍然对同样的错误感到震惊column "price" of relation "Item" does not exist。我在这里想念什么?我的迁移代码是否正确?

另外,我知道如果不对模型进行任何更改,我可以注释掉迁移配置,因为它们不需要在我每次运行服务时都运行。那是对的吗?

4

1 回答 1

3

使用您的代码,您还没有添加新的迁移。您已经实现了手动初始迁移,但初始迁移已按要求运行(migrations.add(model: Item.self, database: .psql)。要创建新迁移,您需要以下内容:

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()
    }
}

然后您需要将其添加到configure

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

于 2019-05-02T06:38:52.693 回答