了解 Vapor-Fluent 中的迁移(服务器端 Swift)
Understanding Migrations in Vapor-Fluent (Server side Swift)
我正在 Swift 使用 Vapor 框架编写 Web 服务。
我有一个名为 Item
的模型。最初它只有 name 和 id 属性。
typealias VaporModel = Content & PostgreSQLModel & Parameter
final class Item: VaporModel {
var id: Int?
var name: String
}
在我为模型配置控制器并添加路由后,当我点击 post 项目请求时,我收到错误 Model.defaultDatabase is required to use as DatabaseConnectable
。我认为错误是因为我没有在 configure.swift
中将 Item
添加到 Migrations
并且在将 Item
符合 PostgreSQLMigration
.[=27= 之后我做了同样的事情]
var migrations = MigrationConfig()
migrations.add(model: Item.self, database: .psql)
services.register(migrations)
现在,我可以点击 post 请求并在数据库中创建项目。
所以我了解到 Migration
协议为模型创建了默认模式,并向数据库添加了一个新的 table,并将模型的属性作为列。
现在我想在我的项目 class 中添加一个 属性,例如 price
。现在,当我点击 post 请求时,我得到的错误是 column "price" of relation "Item" does not exist
。
我假设迁移协议将能够识别模式更改和我的 table 的列(这是我在为我的 iOS 应用程序使用 Realm 时所习惯的)。但我错了,我通读了迁移文档并在迁移中实现了 prepare
和 revert
方法,如下所示。
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
。我在这里错过了什么?我的迁移代码正确吗?
此外,我知道如果不对模型进行任何更改,我可以注释掉迁移配置,因为它们不需要 运行 每次我 运行 服务。对吗?
您的代码还没有添加新的迁移。您已实施手动初始迁移,但初始迁移已按要求 运行(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)
我正在 Swift 使用 Vapor 框架编写 Web 服务。
我有一个名为 Item
的模型。最初它只有 name 和 id 属性。
typealias VaporModel = Content & PostgreSQLModel & Parameter
final class Item: VaporModel {
var id: Int?
var name: String
}
在我为模型配置控制器并添加路由后,当我点击 post 项目请求时,我收到错误 Model.defaultDatabase is required to use as DatabaseConnectable
。我认为错误是因为我没有在 configure.swift
中将 Item
添加到 Migrations
并且在将 Item
符合 PostgreSQLMigration
.[=27= 之后我做了同样的事情]
var migrations = MigrationConfig()
migrations.add(model: Item.self, database: .psql)
services.register(migrations)
现在,我可以点击 post 请求并在数据库中创建项目。
所以我了解到 Migration
协议为模型创建了默认模式,并向数据库添加了一个新的 table,并将模型的属性作为列。
现在我想在我的项目 class 中添加一个 属性,例如 price
。现在,当我点击 post 请求时,我得到的错误是 column "price" of relation "Item" does not exist
。
我假设迁移协议将能够识别模式更改和我的 table 的列(这是我在为我的 iOS 应用程序使用 Realm 时所习惯的)。但我错了,我通读了迁移文档并在迁移中实现了 prepare
和 revert
方法,如下所示。
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
。我在这里错过了什么?我的迁移代码正确吗?
此外,我知道如果不对模型进行任何更改,我可以注释掉迁移配置,因为它们不需要 运行 每次我 运行 服务。对吗?
您的代码还没有添加新的迁移。您已实施手动初始迁移,但初始迁移已按要求 运行(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)