Prisma中处理MySQL Point数据类型的可行实现方案咨询
Prisma + Apollo Server 适配MySQL Point类型解决方案
手动将Unsupported("point")改为string类型失败的原因:Prisma会将string类型的字段值直接作为普通字符串传给MySQL,而MySQL Point类型为空间二进制存储格式,无法直接接收字符串格式的坐标,必须通过空间函数转换后才可读写。
可选实现方案
方案1:保留Unsupported类型 + 原生SQL操作
直接保留Prisma pull后自动生成的
location Unsupported("point")定义,Prisma会自动跳过该字段的常规CRUD校验,所有涉及location字段的读写操作都通过prisma.$queryRaw/prisma.$executeRaw执行原生SQL,配合MySQL空间函数完成类型转换:- 写入时用
ST_GeomFromText()将WKT格式的坐标字符串转为Point类型 - 查询时用
ST_AsText()将Point类型转为WKT字符串返回
示例代码:
// 写入数据 const lng = 116.403874 const lat = 39.914885 await prisma.$executeRaw` INSERT INTO your_table (name, location) VALUES (${'测试地点'}, ST_GeomFromText(${`POINT(${lng} ${lat})`})) ` // 查询数据 const places = await prisma.$queryRaw` SELECT id, name, ST_AsText(location) AS location FROM your_table ` // 返回的location为格式如"POINT(116.403874 39.914885)"的字符串,可自行封装工具函数解析为{lng, lat}结构返回给前端- 写入时用
方案2:冗余字段 + 触发器自动同步
适合不想大量编写原生SQL的场景,步骤如下:
- 在MySQL对应表中新增
location_str字段,类型设为varchar(255),用于存储WKT格式的坐标字符串 - 新建MySQL触发器,实现
location和location_str的自动同步:插入/更新时自动将location_str转为Point存入location字段 - 执行
prisma db pull后,Prisma会自动识别location_str为string类型,常规CRUD直接操作该字段即可
触发器示例SQL:
-- 插入时同步 CREATE TRIGGER trg_location_insert BEFORE INSERT ON your_table FOR EACH ROW SET NEW.location = ST_GeomFromText(NEW.location_str); -- 更新时同步 CREATE TRIGGER trg_location_update BEFORE UPDATE ON your_table FOR EACH ROW SET NEW.location = ST_GeomFromText(NEW.location_str);空间索引仍可建立在
location字段上,需要做空间范围查询时再配合原生SQL操作location字段即可。- 在MySQL对应表中新增
方案3:Prisma扩展封装操作
可以基于Prisma的扩展(Extension)能力,将涉及Point字段的原生SQL逻辑封装为模型自定义方法,对外暴露和原生Prisma方法一致的调用接口,上层Apollo Resolver无需感知原生SQL的存在,降低业务代码的侵入性。
内容的提问来源于stack exchange,提问作者Walter Díaz
相关产品推荐
相关产品推荐

