用 Rust 编写的 Prisma 查询引擎一直是 Prisma ORM 的核心部分。它为未来而开发,但已不再与 Prisma ORM 当前的方向兼容。请继续阅读,了解更多关于我们将从 Rust 重写为 TypeScript 的信息。
Prisma 现在在做什么?!
在我们最近发布的 ORM 宣言 中,我们描述了未来几个月和几年内如何管理 Prisma ORM。其中一个小细节是以下这段话
我们正在通过将 Prisma 的核心逻辑从 Rust 迁移到 TypeScript,并重新设计 ORM 以使其更易于定制和扩展来解决此问题。
这在我们的文章中可能只是一句话,但它引起了不少反响
例如,我们非常喜欢 Theo 的这段视频
总而言之,这些反应是相当合理的。Rust 查询引擎从一开始就伴随 Prisma ORM。我们在网上看到的讨论很棒,但我们也想介入并提供一些更新,因为我们的 TypeScript 实现即将进入早期访问阶段。
简而言之,我们想让社区中的每个人都知道 哪些方面正在改变、这些改变背后的动机以及这些改变将如何实施。
Prisma 为什么选择 Rust?
在我们探索 Prisma ORM 的未来之前,我们需要了解为什么 Prisma ORM 使用 Rust 引擎。当我们开始规划 Prisma 2(现称为 Prisma ORM)时,我们有一个相当清晰的愿景:我们希望为尽可能多的语言构建 ORM——TypeScript、Go、Python、Scala、Rust 等。我们需要一个能够相对容易地添加对新语言支持的解决方案。Rust 的性能优势和系统级方法使其成为这个核心查询引擎的自然选择。
这个决定也是 GraphCool 和 Prisma 1 工作成果的延续。这些早期解决方案的核心、可部署的基础设施演变成了基于 Rust 的查询引擎——一个旨在处理生成 SQL 查询、管理连接池和从数据库返回结果的二进制文件。这使得像 prisma-client-js
这样的特定语言客户端能够保持轻量级,作为引擎之上的层。
为什么放弃 Rust?
虽然拥有强大的 Rust 引擎帮助我们快速提供了出色的性能,但我们后来发现它带来了一些显著的挑战
- 技能壁垒: 为查询引擎贡献代码需要同时精通 Rust 和 TypeScript,这限制了社区参与的机会。
- 部署复杂性: 每个操作系统和 OpenSSL 库版本都需要自己的二进制文件,这使得部署复杂化并减缓了开发速度。
- 兼容性问题: 现代 JavaScript 运行时、无服务器和边缘环境并非总是与大型 Rust 二进制文件兼容,这限制了 Prisma 的部署方式和位置。
此外,查询引擎的核心优势——支持多种客户端的能力——已不再是我们的重点。Prisma ORM 是一个 TypeScript 项目,虽然我们支持社区客户端,但我们不会在内部开发它们。
考虑到这些因素,并加上我们致力于构建一个包容的、社区驱动的生态系统(如我们的 ORM 宣言 中所述),我们决定 将 Rust 查询引擎中尽可能多的部分迁移到 TypeScript——简化贡献并减少部署难题,同时不牺牲 Prisma ORM 用户熟悉和喜爱的开发者体验。
重新定义查询执行
我们在早期访问中引入的主要架构变化涉及将查询执行和数据库结果处理从 Rust 迁移到 TypeScript。
为了理解这一变化,我们来回顾一下当前的查询引擎设置。
当前 Prisma ORM 查询的执行方式
目前,您可以使用 Prisma ORM 查询数据库,主要有两种方式:
- 使用用 Rust 编写的数据库驱动程序。
- 使用用 TypeScript 编写的 驱动程序适配器 和驱动程序。
在第一种方法中,Prisma ORM 查询被传递给用 Rust 编写的查询引擎。该引擎管理从构建查询计划到执行查询并将结果返回给 JavaScript 客户端的所有事务
然而,这种架构无法支持仅提供 JavaScript 驱动程序的数据库,例如 D1 和 Turso。为了解决这一限制,我们引入了驱动程序适配器。
使用驱动程序适配器时,查询引擎仍然生成查询计划和 SQL 语句。但是,执行通过驱动程序适配器委托给数据库
这种方法实现了与 JavaScript 驱动程序的兼容,但也引入了一个权衡:数据必须从 JavaScript 序列化到 Rust,然后再返回到 JavaScript,这降低了效率并抵消了这种方法的一些优势。
未来 Prisma ORM 查询的执行方式
在新架构中,驱动程序适配器仍将使用。然而,Prisma ORM 将不再依赖于基于 Rust 的查询引擎,而是将查询传递给一个 WASM 编译器,该编译器将返回查询计划。然后,该计划将 完全在 TypeScript 中执行。
这种简化的架构带来了几个直接的好处
- 保留对成熟的 JavaScript 数据库驱动程序的支持。
- 减少了 JavaScript 和 Rust 之间的数据转换需求。
- 最大限度地减少了 Rust 和 JavaScript 之间的数据传输量。
- 消除了分发外部二进制文件的需求,因为查询编译器不再依赖于系统特定的工具。
通过将查询执行转移到 TypeScript,我们精简了架构,提高了开发者的兼容性和性能。
即将到来的简化体验
跨语言迁移逻辑是一个重大的转变,但我们正在逐步进行,以最大限度地减少干扰。尽管这些变化意义重大,但我们的首要任务是确保平稳过渡,保持您对 Prisma 的简洁性和可靠性期望。在这次迁移中,我们不仅解决了当前的挑战,还在为增强的开发者体验奠定基础。
平稳过渡的步骤
我们的工程团队正在逐步将查询引擎逻辑迁移到代码库的 TypeScript 端。目前无法迁移的组件正被重新打包到一个 WASM 文件中,该文件包含在 @prisma/client
npm 模块中。该 WASM 文件充当查询编译器,简化了工作流程,而不会带来显著的 API 变化。
例如,我们计划移除对 binaryTargets
的要求,进一步简化开发者体验。总的来说,Prisma ORM 的体验将保持熟悉和直观。
开启未来机遇
这次迁移不仅是为了解决当前的挑战,它还为创新创造了新的机会。事实上,查询编译器为我们的团队和社区探索许多可能性提供了便利。例如,使用参数化查询计划可以实现 保存查询计划以供重复使用 来加快执行速度。另一个方向是在编译时构建初始查询计划,进一步减少运行时计算需求。
我们对这些可能性感到兴奋,并渴望听到您的想法!请在我们的 GitHub 或 Discord 上加入讨论。
帮助我们构建更好的 Prisma ORM 体验
这个项目是让 Prisma ORM 对每个人都更好的重要一步。其核心在于,Prisma ORM 是为像您这样的开发者而构建的。您的反馈和协作对这一旅程至关重要。
您可以通过以下方式提供帮助:
- 提交问题,报告错误或建议新功能。
- 使用讨论区分享您的想法。
- 加入我们的 Discord,参与社区活动和开发者问答。
最后,测试我们的早期访问客户端!我们将在 GitHub 和 Discord 上分享更新。
这是 Prisma 令人兴奋的时刻,前方还有更多的改进和机会。感谢您激励我们成长,并成为这一旅程的一部分。
想成为第一批试用我们新的早期访问客户端的用户吗? 在 X 上关注我们 并 加入我们的 Discord,随时获取最新信息。
不要错过下一篇文章!
订阅 Prisma 新闻通讯