You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用TypeORM在PostgreSQL中存储含JSON对象数组的用户实体?

我明白你的问题了——你在使用TypeORM的嵌入实体(About)时,想要存储一个自定义对象数组(Softwares[]),但TypeORM没有原生支持这种类型,而且尝试用关联关系(ManyToOne)也不奏效,因为嵌入实体是和User存在同一张表中的,不是独立的实体。

下面是具体的解决方案:

核心思路

因为About是嵌入实体(通过@Column(() => About)实现),它的所有字段都会被映射到User表的列中,而不是生成单独的表。所以我们不能用关联关系(比如ManyToOne)来处理softwares数组,而是需要把它作为一个JSON类型的列存储,同时处理好TypeScript类和数据库JSON格式之间的转换。

具体实现步骤

  1. 选择合适的JSON列类型:根据你的数据库选择对应的类型,比如PostgreSQL推荐用jsonb(支持索引和更高效的查询),MySQL/MariaDB用json,SQLite可以用text(但要手动处理JSON转换)。

  2. 为softwares字段添加TypeORM Column配置:在About类的softwares字段上添加@Column装饰器,指定类型为JSON,并配置转换器(transformer)来实现Softwares[]和数据库JSON的互相转换。

修改后的About类代码如下:

@ObjectType()
export class About {
  @Field( { nullable: true } )
  @Column("text", { nullable: true })
  about_header_message: string;

  // 修改这里的配置
  @Field(() => [Softwares], { nullable: true })
  @Column({
    type: 'jsonb', // 如果你用PostgreSQL,推荐jsonb;用MySQL的话改成'json'
    nullable: true,
    transformer: {
      // 把Softwares数组转换成数据库能存储的JSON格式
      to: (value: Softwares[]) => value,
      // 把数据库返回的JSON转换成Softwares数组(如果需要类实例,用Object.assign)
      from: (value: any) => {
        if (!Array.isArray(value)) return [];
        return value.map((item: any) => Object.assign(new Softwares(), item));
      },
    },
  })
  softwares: Softwares[];

  @Field(() => [[String]], { nullable: true })
  @Column("text", { nullable: true, array: true })
  info: string[][];
}

为什么关联关系行不通?

你之前尝试的ManyToOne是用于独立实体之间的关联,比如一个User关联多个独立的Software实体(对应单独的software表)。但你的场景中,Softwares是属于About嵌入实体的一部分,它的数据和User存在同一张表中,不是单独的表,所以关联关系不适用。

验证效果

这样配置后:

  • TypeORM会把softwares数组作为JSON类型存储到User表的aboutSoftwares列(嵌入实体的字段会自动加上前缀)
  • TypeGraphQL的字段配置保持不变,所以GET请求返回的结构依然和你预期的一致
  • 当你从数据库查询User时,transformer会自动把JSON数据转换成Softwares类的实例数组

额外注意事项

  • 如果你的数据库不支持原生JSON类型(比如旧版本的SQLite),可以把类型设为text,然后在transformer的to方法里用JSON.stringify(value)from方法里用JSON.parse(value)来处理
  • 如果你不需要Softwares的类实例,只是普通的JS对象,transformer的from方法可以简化为(value: any) => value || []
  • 如果你开启了TypeORM的synchronize: true,它会自动帮你在User表中创建对应的JSON列;如果是已有数据库,需要手动添加该列

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

火山引擎 最新活动