Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.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
Swift 5.2 Xcode 11.4 Vapor 4.0.0我应该如何在我的模型中编码PK?_Swift_Xcode_Postgresql_Vapor - Fatal编程技术网

Swift 5.2 Xcode 11.4 Vapor 4.0.0我应该如何在我的模型中编码PK?

Swift 5.2 Xcode 11.4 Vapor 4.0.0我应该如何在我的模型中编码PK?,swift,xcode,postgresql,vapor,Swift,Xcode,Postgresql,Vapor,我的Package.swift文件如下所示: .package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc"), .package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-rc"), .package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0-rc

我的
Package.swift
文件如下所示:

.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0-rc")
app.databases.use(.postgres(
    hostname: Environment.get("DATABASE_HOST") ?? "localhost",
    username: Environment.get("DATABASE_USERNAME") ?? "postgres",
    password: Environment.get("DATABASE_PASSWORD") ?? "secret",
    database: Environment.get("DATABASE_NAME") ?? "mydb2"
), as: .psql)
import Fluent
import Vapor


final class Complaint: Model, Content {

    static let schema = "cw_complaint5"

    @ID(key: .id)
    var id: UUID?

    @Field(key: "issue_description")
    var issue_description: String

    // etc.
    init() { }
}
mydb2=# \d+ cw_complaint5
                                              Table "public.cw_complaint5"
        Column        |          Type           | Collation | Nullable | Default | Storage  | Stats target | Description 
----------------------+-------------------------+-----------+----------+---------+----------+--------------+-------------
 id                   | integer                 |           | not null |         | plain    |              | 
 row                  | smallint                |           |          |         | plain    |              | 
 document_number      | integer                 |           | not null |         | plain    |              |
...etc...
county_id            | integer                 |           |          |         | plain    |              | 
 city_id              | integer                 |           |          |         | plain    |              | 
 operator_id          | integer                 |           |          |         | plain    |              | 
Indexes:
    "cw_complaint5_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "cw_complaint5_row_check" CHECK ("row" >= 0)
Foreign-key constraints:
    "cw_complaint5_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cw_city5(id)
    "cw_complaint5_county_id_fkey" FOREIGN KEY (county_id) REFERENCES cw_county5(id)
    "cw_complaint5_operator_id_fkey" FOREIGN KEY (operator_id) REFERENCES cw_operator5(id)

(END)
{"id":729,"issue_description":"test","document_number":99,"api_state_code":88,"api_county_code":11,"section":22,"city_id":51,"county_id":56,"operator_id":4415}
我的
config.swift
文件如下所示:

.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0-rc")
app.databases.use(.postgres(
    hostname: Environment.get("DATABASE_HOST") ?? "localhost",
    username: Environment.get("DATABASE_USERNAME") ?? "postgres",
    password: Environment.get("DATABASE_PASSWORD") ?? "secret",
    database: Environment.get("DATABASE_NAME") ?? "mydb2"
), as: .psql)
import Fluent
import Vapor


final class Complaint: Model, Content {

    static let schema = "cw_complaint5"

    @ID(key: .id)
    var id: UUID?

    @Field(key: "issue_description")
    var issue_description: String

    // etc.
    init() { }
}
mydb2=# \d+ cw_complaint5
                                              Table "public.cw_complaint5"
        Column        |          Type           | Collation | Nullable | Default | Storage  | Stats target | Description 
----------------------+-------------------------+-----------+----------+---------+----------+--------------+-------------
 id                   | integer                 |           | not null |         | plain    |              | 
 row                  | smallint                |           |          |         | plain    |              | 
 document_number      | integer                 |           | not null |         | plain    |              |
...etc...
county_id            | integer                 |           |          |         | plain    |              | 
 city_id              | integer                 |           |          |         | plain    |              | 
 operator_id          | integer                 |           |          |         | plain    |              | 
Indexes:
    "cw_complaint5_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "cw_complaint5_row_check" CHECK ("row" >= 0)
Foreign-key constraints:
    "cw_complaint5_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cw_city5(id)
    "cw_complaint5_county_id_fkey" FOREIGN KEY (county_id) REFERENCES cw_county5(id)
    "cw_complaint5_operator_id_fkey" FOREIGN KEY (operator_id) REFERENCES cw_operator5(id)

(END)
{"id":729,"issue_description":"test","document_number":99,"api_state_code":88,"api_county_code":11,"section":22,"city_id":51,"county_id":56,"operator_id":4415}
我的模型看起来像:

.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0-rc")
app.databases.use(.postgres(
    hostname: Environment.get("DATABASE_HOST") ?? "localhost",
    username: Environment.get("DATABASE_USERNAME") ?? "postgres",
    password: Environment.get("DATABASE_PASSWORD") ?? "secret",
    database: Environment.get("DATABASE_NAME") ?? "mydb2"
), as: .psql)
import Fluent
import Vapor


final class Complaint: Model, Content {

    static let schema = "cw_complaint5"

    @ID(key: .id)
    var id: UUID?

    @Field(key: "issue_description")
    var issue_description: String

    // etc.
    init() { }
}
mydb2=# \d+ cw_complaint5
                                              Table "public.cw_complaint5"
        Column        |          Type           | Collation | Nullable | Default | Storage  | Stats target | Description 
----------------------+-------------------------+-----------+----------+---------+----------+--------------+-------------
 id                   | integer                 |           | not null |         | plain    |              | 
 row                  | smallint                |           |          |         | plain    |              | 
 document_number      | integer                 |           | not null |         | plain    |              |
...etc...
county_id            | integer                 |           |          |         | plain    |              | 
 city_id              | integer                 |           |          |         | plain    |              | 
 operator_id          | integer                 |           |          |         | plain    |              | 
Indexes:
    "cw_complaint5_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "cw_complaint5_row_check" CHECK ("row" >= 0)
Foreign-key constraints:
    "cw_complaint5_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cw_city5(id)
    "cw_complaint5_county_id_fkey" FOREIGN KEY (county_id) REFERENCES cw_county5(id)
    "cw_complaint5_operator_id_fkey" FOREIGN KEY (operator_id) REFERENCES cw_operator5(id)

(END)
{"id":729,"issue_description":"test","document_number":99,"api_state_code":88,"api_county_code":11,"section":22,"city_id":51,"county_id":56,"operator_id":4415}
在Xcode中,项目构建正常,此
GET
路由运行正常:

http://localhost:8080/complaint
但是当我运行
POST
路由时,我在响应正文中得到一个错误:

{
    "error": true,
    "reason": "Value of type 'UUID' required for key 'id'."
}
在Vapor 3中,
POST
路由在插入新行(在JSON请求正文中省略ID)和更新现有行方面都工作得很好。PostgreSQL 11.3上的表说明如下所示:

.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0-rc")
app.databases.use(.postgres(
    hostname: Environment.get("DATABASE_HOST") ?? "localhost",
    username: Environment.get("DATABASE_USERNAME") ?? "postgres",
    password: Environment.get("DATABASE_PASSWORD") ?? "secret",
    database: Environment.get("DATABASE_NAME") ?? "mydb2"
), as: .psql)
import Fluent
import Vapor


final class Complaint: Model, Content {

    static let schema = "cw_complaint5"

    @ID(key: .id)
    var id: UUID?

    @Field(key: "issue_description")
    var issue_description: String

    // etc.
    init() { }
}
mydb2=# \d+ cw_complaint5
                                              Table "public.cw_complaint5"
        Column        |          Type           | Collation | Nullable | Default | Storage  | Stats target | Description 
----------------------+-------------------------+-----------+----------+---------+----------+--------------+-------------
 id                   | integer                 |           | not null |         | plain    |              | 
 row                  | smallint                |           |          |         | plain    |              | 
 document_number      | integer                 |           | not null |         | plain    |              |
...etc...
county_id            | integer                 |           |          |         | plain    |              | 
 city_id              | integer                 |           |          |         | plain    |              | 
 operator_id          | integer                 |           |          |         | plain    |              | 
Indexes:
    "cw_complaint5_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "cw_complaint5_row_check" CHECK ("row" >= 0)
Foreign-key constraints:
    "cw_complaint5_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cw_city5(id)
    "cw_complaint5_county_id_fkey" FOREIGN KEY (county_id) REFERENCES cw_county5(id)
    "cw_complaint5_operator_id_fkey" FOREIGN KEY (operator_id) REFERENCES cw_operator5(id)

(END)
{"id":729,"issue_description":"test","document_number":99,"api_state_code":88,"api_county_code":11,"section":22,"city_id":51,"county_id":56,"operator_id":4415}
失败的
POST
请求(更新现有行)的请求正文如下所示:

.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0-rc"),
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0-rc")
app.databases.use(.postgres(
    hostname: Environment.get("DATABASE_HOST") ?? "localhost",
    username: Environment.get("DATABASE_USERNAME") ?? "postgres",
    password: Environment.get("DATABASE_PASSWORD") ?? "secret",
    database: Environment.get("DATABASE_NAME") ?? "mydb2"
), as: .psql)
import Fluent
import Vapor


final class Complaint: Model, Content {

    static let schema = "cw_complaint5"

    @ID(key: .id)
    var id: UUID?

    @Field(key: "issue_description")
    var issue_description: String

    // etc.
    init() { }
}
mydb2=# \d+ cw_complaint5
                                              Table "public.cw_complaint5"
        Column        |          Type           | Collation | Nullable | Default | Storage  | Stats target | Description 
----------------------+-------------------------+-----------+----------+---------+----------+--------------+-------------
 id                   | integer                 |           | not null |         | plain    |              | 
 row                  | smallint                |           |          |         | plain    |              | 
 document_number      | integer                 |           | not null |         | plain    |              |
...etc...
county_id            | integer                 |           |          |         | plain    |              | 
 city_id              | integer                 |           |          |         | plain    |              | 
 operator_id          | integer                 |           |          |         | plain    |              | 
Indexes:
    "cw_complaint5_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "cw_complaint5_row_check" CHECK ("row" >= 0)
Foreign-key constraints:
    "cw_complaint5_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cw_city5(id)
    "cw_complaint5_county_id_fkey" FOREIGN KEY (county_id) REFERENCES cw_county5(id)
    "cw_complaint5_operator_id_fkey" FOREIGN KEY (operator_id) REFERENCES cw_operator5(id)

(END)
{"id":729,"issue_description":"test","document_number":99,"api_state_code":88,"api_county_code":11,"section":22,"city_id":51,"county_id":56,"operator_id":4415}

这里的问题是
投诉
型号的ID类型是
UUID
,但在
POST
请求正文中,您传递的是
Int
值。由于您要迁移的现有项目已使用整数ID定义了数据库,因此最好的解决方案是更改模型的ID类型

由于Fluent 4尝试支持所有数据库,因此默认情况下它只支持UUID类型。您可以有一个自定义ID类型,如下所示:

@ID(自定义:“ID”,生成者:。数据库)变量ID:Int?
这将允许您的模型使用当前的数据库表结构,并在
POST
请求正文中接受整数ID

您的模型最终将如下所示:

最后一节课投诉:型号、内容{
静态let schema=“cw\u complaint5”
@ID(自定义:“ID”,生成者:。数据库)
变量id:Int?
@字段(关键字:“问题描述”)
变量问题描述:字符串
//等等。
init(){}
}

解决方案:在PostgreSQL中序列化表:

mydb2=# ALTER TABLE cw_complaint5 DROP COLUMN id;

mydb2=# ALTER TABLE cw_complaint5 ADD COLUMN id SERIAL PRIMARY KEY;
然后,要插入一行(在xcode 11.4 vapor 4 fluentpostgresql中),请从POST请求json中删除id,例如:

{"section":1,"operator_id":4415 ... etc.}
要更新现有行,请在json中包含id。routes.swift中的以下命令同时处理插入和更新:

app.post("complaint") { req -> EventLoopFuture<Complaint> in
    let complaint = try req.content.decode(Complaint.self)
    if let id = complaint.id {
        print("60p \(id)") // Optional(6005)
    }
    return complaint.save(on: req.db)
        .map { complaint }
}
app.post(“投诉”){req->EventLoopFuture
让投诉=尝试请求内容解码(投诉.self)
如果let id=complaint.id{
打印(“60p\(id)”//可选(6005)
}
返回投诉。保存(on:req.db)
.map{投诉}
}

您可以显示POST端点的代码吗?好的,这里是(成功的)GET和(不成功的)POST:app.GET(“投诉”){req in complaint.query(on:req.db).all()}app.POST(“投诉”){req->EventLoopFuture in let complaint=try req.content.decode(complaint.self)return complaint.create(on:req.db).map{complaint}我看到它做了一个create,所以我不希望它更新现有的行。如果我从json请求体中删除id并希望它插入一行,我得到:{“error”:true,“reason”:“server:column\“id”的类型是integer,但表达式的类型是uuid(transformAssignedExpr)}我尝试了模型中id的各种排列。这是生成唯一接受的:@id(键:.id)变量id:UUID?如果数据库中的
id
列已经是autoincrement integer,那么您不应该将模型的id更改为
UUID
。要流畅地使用autoincrement,据我所知,您只需将您的id标记为可自动生成的,例如
@id(自定义:“id”,generatedBy:.database)var id:Int?
按照您的建议对id进行编码,并尝试POST插入一行(json请求中没有id),我得到“服务器:列\“id\”中的null值违反了非null约束(ExecConstraints)”