You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vapor/Fluent中schema定义uuid数组字段时子对象无法保存问题

问题产生原因

你遇到的报错已经明确指出了类型不匹配的核心问题:

{"error":true,"reason":"server: column "sources" is of type uuid[] but expression is of type jsonb[] (transformAssignedExpr)"}

具体是两层定义不一致导致的:

  • 数据库迁移中你将sources字段定义为.array(of: .uuid),对应Postgres侧的uuid[]类型,仅支持存储UUID格式的数组
  • 模型层你将sources字段声明为[Coin]类型,Fluent会默认将所有遵循Codable协议的自定义类型序列化为JSONB格式存储,哪怕传入空数组,也会生成JSONB数组类型的写入请求,和数据库要求的UUID数组类型冲突。

正确实现方案

方案1:存储来源Coin的UUID数组(推荐,符合回溯链路的设计初衷)

这种方案仅存储来源Coin的ID,无冗余数据,是最常用的实现方式:

  1. 修改模型层的sources字段定义:
// 原定义 @Field(key: "sources") var sources: [Coin] 替换为
@Field(key: "sources") var sources: [UUID]
  1. 调整初始化方法的赋值逻辑,提取传入Coin实例的ID存入数组:
init(player: User, quantity: Int, type: CreatedFor, sources : [Coin] = []) {
    self.id = id
    self.$player.id = player.id!
    self.quantity = quantity
    self.type = type
    self.sources = sources.compactMap(\.id)
}
  1. 恢复迁移代码中sources字段的注释即可,不需要修改数据库侧的类型定义。

方案2:存储完整的Coin实体信息

如果业务场景需要将来源Coin的全量信息直接存在字段中,不需要关联查询,仅需要修改迁移中的字段类型:

// 原定义 .field("sources", .array(of: .uuid)) 替换为
.field("sources", .array(of: .jsonb))

模型层的sources: [Coin]定义不需要调整,Fluent会自动完成序列化存储。

可选方案:用多对多关联管理来源关系

如果后续需要基于来源Coin做反向查询、统计等操作,更推荐使用Fluent的多对多关联实现:

  • 新建中间表CoinSources,存储当前CoinID、来源CoinID两个关联字段
  • 给Coin模型添加@Siblings修饰符管理来源关联关系,无数据冗余,查询更灵活

内容的提问来源于stack exchange,提问作者Dan Donaldson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 02:24:04