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

Apollo Client+GraphQL+Prisma如何通过非ID字段查询数据?

解决方案

1. 修正查询字段名错误

你的Prisma模型是RecordingFile,但查询里误用了videoFile,这是核心错误之一。Prisma生成的GraphQL查询字段名遵循模型名的小驼峰规则,所以正确的字段名应该是recordingFile/recordingFiles,而非videoFile。但默认情况下,单个recordingFile查询仅支持id参数,这也是你改完字段名后仍报错的原因。

2. 实现按path字段查询

要通过非ID字段(path)查询,需要以下操作:

步骤1:给path字段添加唯一约束(可选但推荐)

如果你的path字段全局唯一,先在Prisma Schema中添加@unique约束,这样能利用findUnique实现高效查询:

model RecordingFile {
  id           String   @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
  name         String
  path         String   @unique  // 添加唯一约束
  duration     Float
  size         Int
  tag          Tag[]
  createdAt    DateTime @default(now()) @db.Timestamptz(6)
  updatedAt    DateTime @default(now()) @updatedAt @db.Timestamptz(6)
}

执行命令更新数据库并重新生成Prisma Client:

npx prisma migrate dev
npx prisma generate

步骤2:自定义GraphQL查询Resolver

若使用Prisma + Apollo Server组合,需添加自定义查询字段并编写Resolver:

更新GraphQL Schema定义

type Query {
  # 保留默认按id查询的字段
  recordingFile(id: String!): RecordingFile
  # 添加按path查询的自定义字段
  recordingFileByPath(path: String!): RecordingFile
}

编写Resolver逻辑

// 假设已初始化Prisma Client实例为prisma
const resolvers = {
  Query: {
    recordingFileByPath: async (_, { path }) => {
      // path唯一时用findUnique,非唯一则改用findFirst
      return await prisma.recordingFile.findUnique({
        where: { path }
      });
    }
  }
};

步骤3:修改前端查询语句

现在可以在React组件中使用新的查询字段:

const FIND_BY_PATH = gql`
query GetExisting($path: String!) {
    recordingFileByPath(path: $path) {
        id
        name
        path
    }
}
`

3. 备选方案:使用列表查询过滤

若不想自定义Resolver,也可以通过recordingFiles列表查询的where参数过滤结果:

const FIND_BY_PATH = gql`
query GetExisting($path: String!) {
    recordingFiles(where: { path: $path }) {
        id
        name
        path
    }
}
`

这种方式会返回所有匹配path的记录,你可以在前端取第一个结果使用。

修正后的React组件代码

import React from "react";
import { gql, useQuery } from "@apollo/client";

interface NodeTableRowParams {
    data: {
        file: {
            name: string,
            path: string
            // ... 其他字段
        }
        // ... 其他字段
    }
}

const FIND_BY_PATH = gql`
query GetExisting($path: String!) {
    recordingFileByPath(path: $path) {
        id
        name
        path
    }
}
`

const NodeTableRow: React.FC<NodeTableRowParams> = ({data}) => {
    const { loading: loading_findByPath, error: error_findByPath, data: data_findByPath} = useQuery(FIND_BY_PATH, {
        variables: { path: data.file.path }
    });

    if (loading_findByPath) return <div>加载中...</div>;
    if (error_findByPath) return <div>错误:{error_findByPath.message}</div>;

    return (
        <div id="file-list">
            <FileData data={data}/>
            {/* 可使用data_findByPath.recordingFileByPath获取查询结果 */}
        </div>
    );
};

export default NodeTableRow;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:24:51