Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解Vapor Fluent(服务器端Swift)中的迁移_Swift_Postgresql_Fluent_Vapor_Server Side Swift - Fatal编程技术网

了解Vapor Fluent(服务器端Swift)中的迁移

了解Vapor Fluent(服务器端Swift)中的迁移,swift,postgresql,fluent,vapor,server-side-swift,Swift,Postgresql,Fluent,Vapor,Server Side Swift,我正在使用Vapor框架用Swift编写一个web服务 我有一个名为项的模型。最初它只有名称和id属性 typealias VaporModel = Content & PostgreSQLModel & Parameter final class Item: VaporModel { var id: Int? var name: String } 在为模型配置控制器并添加路由之后,当我点击post Item请求时,我得到的错误是model.defaultDat

我正在使用Vapor框架用Swift编写一个web服务

我有一个名为
项的模型
。最初它只有名称和id属性

typealias VaporModel = Content & PostgreSQLModel & Parameter
final class Item: VaporModel {
    var id: Int?
    var name: String
}
在为模型配置控制器并添加路由之后,当我点击post Item请求时,我得到的错误是
model.defaultDatabase必须用作DatabaseConnectable
。我认为错误是因为我没有在
configure.swift
中的
Migrations
中添加
Item
,我在将
Item
postgresqlmigation
一致后也这样做了

var migrations = MigrationConfig()
migrations.add(model: Item.self, database: .psql)
services.register(migrations)
现在,我可以点击post请求并在数据库中创建项

因此我了解到,
迁移
协议为模型创建默认模式,并向数据库中添加一个新表,其中模型的属性为列

现在我想向我的Item类添加一个属性,例如
price
。现在,当我点击post请求时,我得到了错误,因为关系“Item”的
列“price”不存在
。 我假设迁移协议将能够识别模式更改和我的表中的列(这是我在为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) { }
    }
} 
扩展项:PostgreSQLMigration{
静态func prepare(在conn:PostgreSQLConnection上)->Future{
返回Database.create(self,on:conn){creator in
creator.field(用于:\.价格)
}
}
静态func恢复(在连接上:PostgreSQLConnection)->EventLoopFuture{
return Future.map(on:connection){}
}
} 
我仍然被同样的错误所震惊,
关系“Item”的“price”列不存在
。我错过了什么?我的迁移代码正确吗


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

您的代码没有添加新的迁移。您已经实现了手动初始迁移,但初始迁移已按要求运行(
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()
    }
}
struct ItemAddPriceMigration:迁移{
typealias数据库=PostgreSQLDatabase
静态func prepare(在conn:PostgreSQLConnection上)->EventLoopFuture{
返回Database.update(Item.self,on:conn){builder in
builder.field(用于:\.价格)
}
}
静态func恢复(在conn:PostgreSQLConnection上)->EventLoopFuture{
返回连接未来()
}
}
然后您需要将其添加到
配置中:


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

我已经尝试过这种方法,但没有成功。您共享的代码没有生成,并且在我将
self
更改为
Item.self
时生成了它。然后,当我运行该服务时,我在顶层遇到了错误
错误:⚠️ PostgreSQL错误:关系“Item”已存在
抱歉,它是
更新
,当然不是
创建
。回答更新。谢谢。这解决了该错误。我应该如何为新列提供默认值?因为我得到的是错误
列“price”包含空值
假设
price
是一个
Int
您将执行的
builder.field(对于:\.price,类型:.bigint,postgresqlcolumnstraint.default(.literal(1)))
对于1的价格。现在我想将价格设置为双/浮动,我可以按照上面的方法进行迁移,并设置默认值,但这会将数据库中的所有项目价格设置为默认值。如何迁移每个项目的价格?