如何在 FluentProvider for VapoR语言 Swift 中使用字符串化的 UUID 作为主键



我正在开发一个Vapor API,在使用FluentProvider时,我正在尝试基于App/Models/Users.swift中的Users模型创建一个Users表:

final class Users: Model {
let storage = Storage()
// Properties
let UserUUID:  String
let FirstName: String
let LastName:  String
let EMail:     String
let Password:  String
// Initializer
init( userUUID:  String,
firstName: String, lastName: String, 
email:     String, password: String ) 
{
self.UserUUID  = userUUID
self.FirstName = firstName
self.LastName  = lastName
self.EMail     = email
self.Password  = password
}
init(row: Row) throws {
UserUUID  = try row.get("UserUUID" )
FirstName = try row.get("FirstName")
LastName  = try row.get("LastName" )
EMail     = try row.get("EMail"    )
Password  = try row.get("Password" )
}
func makeRow() throws -> Row {
var row = Row()
try row.set("UserUUID",  UserUUID )
try row.set("FirstName", FirstName)
try row.set("LastName",  LastName )
try row.set("EMail",     EMail    )
try row.set("Password",  Password )
return row
}
}

默认情况下,这是与 SQLite 提供程序关联的。我想使用字符串格式的 UUID 作为此表的主键。

我的问题是,在为此模型编写准备时,它只希望主键命名为"id",使用builder.id()创建。如果我尝试创建自定义列并将其用作主键/标识符,则会引发错误。准备代码如下:

extension Users: Preparation {
static func prepare(_ database: Database) throws {
try database.create(self) { builder in
/* builder.id()    <- intentionally omitted. */
builder.custom( // <- Attempted in place of builder.id()
"UserUUID",  
type:"VARCHAR(255) PRIMARY KEY", 
optional: false, 
unique: true
) 
builder.string("FirstName", optional: false, unique: false)
builder.string("LastName",  optional: false, unique: false)
builder.string("EMail",     optional: false, unique: true)
builder.string("Password",  optional: false, unique: false)
}
}
static func revert(_ database: Database) throws {
try database.delete(self)
}
}

从 API 调用关联路由时产生的错误:

POST /service/users/new
[SQLite.StatusError: error("table userss has no column named id")]
Conform 'SQLite.StatusError' to Debugging.Debuggable to provide more 
debug information.

如果我理解正确,它只会接受一个名为"id"的 ID 列,该列显然只能通过使用builder.id()方法生成,该方法仅将一个自动递增的整数分配给 ID。

所以我的问题是:

  1. 是否可以使用特定列作为主键/标识符 列,如果是这样,如何?

  2. "UserUUID"重命名为"id"但保留其余部分 属性相同也可以作为解决方案?

看起来 Fluent 知道如何通过在Entity上使用静态变量来创建 ID,这是您的User模型符合的协议。具体来说,看起来您需要覆盖以下两个变量:

final class Users: Model {
static var idKey: String {
return "UserUUID"
}
static var idType: IdentifierType {
return .uuid
}
}

现在,如果您取消注释builder.id()行,则应正确创建 id。

我在 Vapor 项目中使用 UUID 没有问题,并且不必在准备过程中编写自定义代码。

您是否尝试过在fluent.json中设置idType?

"idType": "uuid"

请注意,我指的是蒸汽 2.4

最新更新