🚀 使用 Prisma 连接 OceanBase

引言

  • 众所周知,OceanBase 是一款分布式数据库,同时兼容 MySQL 和 Oracle。Prisma 则是新一代的 Node.js ORM 框架,支持 MySQL、PostgreSQL 等多种查询引擎,能够极大提升数据库的开发效率和体验。那两者能否一起使用呢?

  • 尝试了下,第一步连接数据库就遇到了 Unknown system variable 'socket'的问题:

OceanBase 不兼容 socket 变量

Prisma prefer_socket 参数不生效

  • 那能否在 Prisma 侧绕过呢?经查询,Prisma 支持数据库连接串参数 prefer_socket,在建连时可关闭 socket 变量查询,从而避免该问题。

DATABASE_URL="{YOUR_DATABASE_URL}?prefer_socket=false"

  • 经验证,仍然出现刚刚的 Unknown system variable 'socket'问题,说明 prefer_socket=false并未生效。

问题排查: 梳理 Prisma 架构

  • 为了定位问题,对 Prisma 架构和包的嵌套逻辑进行了梳理。

问题根因: mysql_async 驱动 bug

问题解决: 自行构建和托管 Prisma 引擎

  • 随着包括 OceanBase 和 TDSQL 在内越来越多的用户反馈,亟需解决 Prisma prefer_socket=false不生效的问题。
  • 查阅 Prisma 文档之后,发现 Prisma 支持通过环境变量自定义引擎的下载地址和版本。

# 自定义 Prisma 引擎下载地址,默认值为 https://binaries.prisma.sh

PRISMA_ENGINES_MIRROR=""

# 自定义 Prisma 引擎版本,值为 https://github.com/prisma/prisma-engines 仓库的 commit id

BINARY_DOWNLOAD_VERSION=""

  • 申请 AWS S3 Bucket,用于托管 Prisma 的二进制引擎。按需修改构建流水线 .github/workflows/build-engines.yml配置 (可详见 commit),流水线执行成功即可自动上传引擎产物到 S3 上。
流水线构建 将引擎托管到 AWS S3

使用方案: 配置环境变量

  • 数据库连接串增加 prefer_socket=false参数:

DATABASE_URL="{YOUR_DATABASE_URL}?prefer_socket=false"

  • 将环境变量写入 ~/.bashrc~/.zshrc(取决于使用的 shell 类型) 并 source,以保证全局生效:

  • :loudspeaker: 注意: 不能在 .env 文件中配置,否则读取不到

  • :loudspeaker: 注意: 尽量将环境变量配置到全局,否则新开命令行窗口会丢失


export PRISMA_ENGINES_MIRROR=https://oceanbase-prisma-builds.s3.ap-southeast-1.amazonaws.com

export BINARY_DOWNLOAD_VERSION=96fa66f2f130d66795d9f79dd431c678a9c7104e

  • 输入 env命令,查看环境变量是否生效:

  • 重装依赖 (要求prisma@prisma/client 版本在 ^5.20.0及以上):

rm -rf node_modules && npm i

  • 连接成功:

npx prisma db pull

  • :rainbow: 调试小技巧: 如果按上述步骤操作仍然连接不上,或者想了解 Prisma 内部的执行流程,重装依赖时可以使用以下命令,会将 Prisma 内部的 debug 信息打印出来。

rm -rf node_modules && DEBUG="prisma:*" npm i --foreground-scripts

后续规划

3 个赞

好文