Prisma多数据库场景下GraphQL解析器与类型定义的关联配置
多数据库/Schema下GraphQL与Prisma的适配方案
针对你同时操作两个PostgreSQL数据库、搭配Prisma和GraphQL的场景,核心思路是给不同数据库的GraphQL模块做明确归类,并让解析器绑定对应数据库的Prisma客户端,具体实现步骤如下:
1. 调整GraphQL目录结构(按数据库归类)
先把原有的GraphQL文件按所属数据库拆分,避免模块混乱:
- graphql --- db1 --- table1 ------ resolvers.js ------ typedefs.js --- resolvers.js # 合并db1下所有表的resolvers --- typedefs.js # 合并db1下所有表的typedefs --- db2 --- table2 ------ resolvers.js ------ typedefs.js --- resolvers.js --- typedefs.js --- resolvers.js # 最终合并db1和db2的根resolvers --- typedefs.js # 最终合并db1和db2的根typedefs
2. 创建独立的Prisma客户端实例
每个数据库对应一个独立的Prisma客户端,避免客户端实例混用:
- 在
prisma1目录下执行生成命令:npx prisma generate --schema=./schema1.prisma,生成专属客户端 - 新建
prisma1/client.js:
import { PrismaClient } from './generated/client'; const prisma1 = new PrismaClient({ datasources: { db: { url: process.env.DATABASE_URL_1 } } }); export default prisma1;
- 同理处理
prisma2,新建prisma2/client.js:
import { PrismaClient } from './generated/client'; const prisma2 = new PrismaClient({ datasources: { db: { url: process.env.DATABASE_URL_2 } } }); export default prisma2;
3. 让Resolver绑定对应数据库的Prisma客户端
有两种实用方式实现绑定:
方式一:直接在Resolver中导入对应客户端
比如graphql/db1/table1/resolvers.js:
import prisma1 from '../../../prisma1/client'; export const resolvers = { Query: { getTable1Data: async () => { return prisma1.table1.findMany(); } } };
方式二:通过GraphQL上下文(Context)注入(推荐)
在服务器初始化时,把两个Prisma客户端注入上下文,Resolver通过上下文获取对应实例:index.js(以Apollo Server为例):
import { ApolloServer } from '@apollo/server'; import { startStandaloneServer } from '@apollo/server/standalone'; import { mergeTypeDefs, mergeResolvers } from '@graphql-tools/merge'; import prisma1 from './prisma1/client'; import prisma2 from './prisma2/client'; import db1TypeDefs from './graphql/db1/typedefs'; import db1Resolvers from './graphql/db1/resolvers'; import db2TypeDefs from './graphql/db2/typedefs'; import db2Resolvers from './graphql/db2/resolvers'; // 合并所有类型定义和解析器 const mergedTypeDefs = mergeTypeDefs([db1TypeDefs, db2TypeDefs]); const mergedResolvers = mergeResolvers([db1Resolvers, db2Resolvers]); const server = new ApolloServer({ typeDefs: mergedTypeDefs, resolvers: mergedResolvers }); // 启动服务器并注入上下文 const { url } = await startStandaloneServer(server, { context: async () => ({ prisma1, prisma2 }) });
然后在Resolver中通过上下文调用对应客户端:graphql/db1/table1/resolvers.js:
export const resolvers = { Query: { getTable1Data: async (_, __, context) => { return context.prisma1.table1.findMany(); } } };
4. 处理类型命名冲突
如果两个数据库存在同名表,需要在GraphQL类型定义中加前缀区分,比如将Table1改为DB1_Table1,避免类型名重复导致服务器报错。
内容的提问来源于stack exchange,提问作者Yoo SungHee
相关产品推荐
相关产品推荐

