首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在数据库中定义Prisma字段,即Json类型,但将其映射到已定义的TypeGraphQL对象?

如何在数据库中定义Prisma字段,即Json类型,但将其映射到已定义的TypeGraphQL对象?
EN

Stack Overflow用户
提问于 2022-09-30 22:51:42
回答 1查看 621关注 0票数 3

我想在我的Json?文件中创建一个Json?类型的字段,但是我想将它映射到一个TypeGraphQL @ObjectType()类。我不希望对象的数据库中有一个表。我想将它作为json存储在db中,但我希望确保它符合我在gql模式中定义的类型。这个是可能的吗?我是,而不是使用typegraphql-prisma包的。下面是一个简化的示例(这里的代码可能并不完美,因为我无法复制/粘贴):

只有schema.prisma中的一张桌子。commentsJson类型,而不是定义与Comment模型/表的一对多关系。

schema.prisma

代码语言:javascript
运行
复制
model Post {
  id       Int     @id @default(autoincrement())
  title    String
  content  String
  comments Json?
}

但是在我的TypeGraphQL类型中,我想定义组成Comment的属性。我不想将comments定义为Prisma.JsonValue。我希望它是一个像Comment[]一样的列表。

types.ts

代码语言:javascript
运行
复制
@ObjectType()
export class Comment {
  @Field()
  id!:  number;

  @Field()
  content!: string;
}


@ObjectType()
export class Post {
  @Field()
  id!:  number;

  @Field()
  title!: string;

  @Field()
  content!: string;

  @Field((type) => [Comment], { nullable: true })
  comments?: Comment[] | null;
}

当我试图查询时,根据我尝试的不同事情,我会得到不同的TypeScript错误。它不喜欢我用JSON作为我的Prisma模型,用对象来定义我的comments类型。可以这样定义我的数据库和类型吗?在对象和JSON之间进行“转换”的最佳方法是什么?谢谢!

代码语言:javascript
运行
复制
import { Post as PostDb } from '@prisma/client';
import { Post } from './types.ts';

@Resolver(Post)
export class PostResolver {
  @Query((returns) => Post, { nullable: true })
  async getPostByTitle(title: string): Promise<PostDb | null> {
    try {
      return prismaClient.post.findUnique({
        where: { title }
      });
    } catch(error) {
      throw new GetPostError(error.message);
    }
  }
}
EN

回答 1

Stack Overflow用户

发布于 2022-10-04 14:39:50

目前,据我所知,您必须使用将普通的JSON转换为类型-graphql class的实例。

Comment

添加Expose装饰符,允许使用excludeExtraneousValues:当将普通值转换为类时,应从值中排除无关属性。

代码语言:javascript
运行
复制
// ...
import { Expose } from 'class-transformer';

@ObjectType()
export class Comment {
  @Field()
  @Expose()
  id!: number;

  @Field()
  @Expose()
  content!: string;
}

PostResolver

每当找到Prisma Post类时,使用实用程序函数mapPost将其映射到type-graphql类实例。

注意,对于每个JSON注释,我们使用函数plainToInstanceclass-transformer库将其转换为(type-graphql) Comment类的实例。

代码语言:javascript
运行
复制
// ...
import type { Prisma, Post as PrismaPost } from '@prisma/client';
import { plainToInstance } from 'class-transformer';

@Resolver(Post)
export class PostResolver {
  /**
   * Map an instance of a Prisma Post class to
   *  an instance of a type-graphql class.
   *
   * @param post - Prisma Post class instance
   * @returns type-graphql Post class instance
   */
  private mapPost(post: PrismaPost): Post {
    return {
      ...post,
      comments: post.comments
        ? (post.comments as Prisma.JsonArray).map((comment) =>
            plainToInstance(Comment, comment, { excludeExtraneousValues: true })
          )
        : null
    };
  }

  @Query(() => Post, { nullable: true })
  async getPostByTitle(title: string): Promise<Post | null> {
    try {
      const post = prismaClient.post.findUnique({
        where: { title }
      });

      // Return null if post not found
      if (!post) return null;

      // Found! Map from Prisma to type-graphql
      return this.mapPost(post);
    } catch(error) {
      throw new GetPostError(error.message);
    }
  }
}

示例

假设您将JSON Comment保存为:

代码语言:javascript
运行
复制
[
  {
    "id": 0,
    "content": "Hello"
  },
  {
    "id": 1,
    "content": "World"
  }
]

现在您应该能够执行以下查询:

代码语言:javascript
运行
复制
getPostByTitle(title: "Hello World") {
  id,
  comments {
    content
  }
}

取得以下结果:

代码语言:javascript
运行
复制
{
  "data": {
    "getPostByTitle": {
      "id": 0,
      "comments": [
        {
          "content": "Hello"
        },
        {
          "content": "World"
        }
      ]
    }
  }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73914625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档