postgresql Swift/Vapor中的Postgres jsonb数据

1cklez4t  于 2023-01-05  发布在  PostgreSQL
关注(0)|答案(2)|浏览(149)

我有以下创建jsonb列的Vapor Fluent迁移

public func prepare(on database: Database) -> EventLoopFuture<Void> {
        return database.schema(MyModel.schema)
            .id()
            .field(.name, .custom("VARCHAR(255)"), .required)
            .field(.metadata, .custom("JSONB"), .required)
            .create()
    }

模型如下所示:

public final class MyModel: Model, Content {
    public static let schema = "blah"
    
    @ID(key: .id)
    public var id: UUID?
    
    @Field(key: .metadata)
    public var metadata: Data // This is obviously wrong.
}

你知道如何让Vapor从Postgres jsonb列中检索和设置数据吗?

nhaq1z21

nhaq1z211#

我认为您需要的是在迁移中声明字段时使用.json类型。
下面是我使用入门模板代码编写的一个示例,以供参考:

struct Person: Codable {
    let name: String
}

final class Todo: Model, Content {
    static let schema = "todos"
    
    @ID(key: .id)
    var id: UUID?
    
    @Field(key: "metadata")
    var metadata: [String: String]
    
    @Field(key: "person")
    var person: Person

    init() { }

    init(id: UUID? = nil, metadata: [String: String], person: Person) {
        self.id = id
        self.metadata = metadata
        self.person = person
    }
}

我声明了两个字段metadataperson

struct CreateTodo: Migration {
    func prepare(on database: Database) -> EventLoopFuture<Void> {
        return database.schema("todos")
            .id()
            .field("metadata", .json, .required)
            .field("person", .json, .required)
            .create()
    }

    func revert(on database: Database) -> EventLoopFuture<Void> {
        return database.schema("todos").delete()
    }
}
bmp9r5qi

bmp9r5qi2#

JSONB(蒸汽4)

两全其美-Postgres中的JSONB和此处的类型安全:
1.在迁移中声明.custom("JSONB")类型的数据库列
1.为JSON数据定义数据模型
1.使用您的数据模型作为Fluent模型的相应属性的类型。
序列化/反序列化是现成的。
工作(测试)示例:

struct CreateTodo: AsyncMigration {
    func prepare(on database: Database) async throws {
        try await database.schema("todos")
            .id()
            .field("details", .custom("JSONB"), .required)
            .create()
    }

    func revert(on database: Database) async throws {
        try await database.schema("todos").delete()
    }
}

struct Details: Content {
    var itemA: String
    var itemB: String
}

final class Todo: Model, Content {
    static let schema = "todos"
    
    @ID(key: .id)
    var id: UUID?

    @Field(key: "details")
    var details: Details

    init() { }

    init(id: UUID? = nil, details: Details) {
        self.id = id
        self.details = details
    }
}

测试:

curl localhost:8080/todos
[{"id":"00000000-0000-0000-0000-000000000001","details":{"itemA":"A","itemB":"B"}}]

功能样本库:https://github.com/ruslanvs/JSONBSample

相关问题