2025 年 1 月 30 日

从 Rust 到 TypeScript:Prisma ORM 的新篇章

用 Rust 编写的 Prisma 查询引擎一直是 Prisma ORM 的核心部分。它为未来而开发,但已不再与 Prisma ORM 的当前方向兼容。请继续阅读,了解我们从 Rust 到 TypeScript 的重写。

Prisma ORM Architecture Shift: Why We Moved from Rust to TypeScript

TL;DR:无 Rust ORM 已可用于生产

Prisma ORM 的核心引擎已从基于 Rust 的查询引擎大幅转向更精简的TypeScript/WASM 核心查询编译器)。这种新架构现已可用于生产 (v6.16+),从根本上改善了您的开发者体验 (DX) 和应用程序性能。

  • 无二进制开销:消除了对原生 Rust 二进制文件的依赖,极大地简化了部署并降低了潜在的复杂性问题。
  • 性能:查询速度最高提升 3.4 倍(通过消除跨语言序列化),捆绑包大小减少 90%(从约 14MB 减至 1.6 MB)。
  • 更好地支持不同运行时:更好地支持 Cloudflare Workers、Deno、Bun、Vercel Edge 等部署环境和运行时。

要立即实现这些优势,请参阅新的无 Rust 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 客户端的所有事务。

Prisma ORM communicating with a database

然而,这种架构无法支持只提供 JavaScript 驱动程序的数据库,例如 D1 和 Turso。为了解决这个限制,我们引入了驱动适配器。

使用驱动适配器时,查询引擎仍然开发查询计划并生成 SQL 语句。但是,执行通过驱动适配器委托给数据库。

Prisma ORM communicating with a database via a driver adapter.

这种方法实现了与 JavaScript 驱动程序的兼容性,但也引入了一个权衡:数据必须从 JavaScript 序列化到 Rust,然后再回到 JavaScript,这降低了效率并抵消了这种方法的一些优势。

明日 Prisma ORM 查询的执行

在新架构中,驱动适配器仍将继续使用。然而,Prisma ORM 不再依赖基于 Rust 的查询引擎,而是将查询传递给 WASM 编译器,该编译器将返回查询计划。然后,该计划将完全在 TypeScript 中执行

Prisma ORM communicating with a database in the query compiler project

这种简化的架构带来了几个即时优势:

  • 保留对经验证的 JavaScript 数据库驱动程序的支持。
  • 减少了 JavaScript 和 Rust 之间数据转换的需求。
  • 最小化了 Rust 和 JavaScript 之间传输的数据量。
  • 消除了发送外部二进制文件的需要,因为查询编译器不再依赖于特定于系统的实用程序。

通过将查询执行转移到 TypeScript,我们简化了架构并增强了开发人员的兼容性和性能。

即将到来:更流畅的体验

跨语言的逻辑迁移是一项重大的转变,但我们正在逐步推进,以最大程度地减少中断。虽然这些变化是实质性的,但我们的首要任务是确保平稳过渡,并保持您对 Prisma 所期望的简洁性和可靠性。在这次迁移中,我们不仅解决了当前的挑战,还在为增强的开发者体验奠定基础。

平稳过渡的步骤

我们的工程团队正在逐步将查询引擎逻辑迁移到代码库的 TypeScript 端。目前无法迁移的组件正在重新打包成一个 WASM 文件,并包含在 @prisma/client npm 模块中。这个 WASM 文件充当查询编译器,在不进行重大 API 更改的情况下简化了工作流程。

例如,我们计划取消对 binaryTargets 的要求,进一步简化开发人员体验。总的来说,Prisma ORM 的体验将保持熟悉和直观

解锁未来机遇

这次转型不仅是为了应对当前的挑战,它还为创新创造了新的机会。事实上,查询编译器为我们的团队和社区探索了许多可能性。例如,参数化查询计划的使用可以保存查询计划以供重复使用,从而加快执行速度。另一个途径是在编译时构建初始查询计划,进一步减少运行时计算需求。

我们对这些可能性感到兴奋,并渴望听到您的想法!加入我们在 GitHub 或 Discord 上的讨论。

TL;DR:无 Rust ORM 已可用于生产

帮助我们构建更好的 Prisma ORM 体验

这个项目是让 Prisma ORM 对每个人都更好迈出的重要一步。Prisma ORM 的核心是为像您这样的开发人员构建的。您的反馈和协作对这段旅程至关重要。

以下是您可以提供帮助的方式:

最后,测试我们的早期访问客户端!我们将在 GitHub 和 Discord 上分享更新。

这对 Prisma 来说是一个激动人心的时刻,未来还有更多的改进和机会。感谢您激励我们成长并成为这段旅程的一部分。

想成为第一批尝试我们新的早期访问客户端的人吗?在 X 上关注我们加入我们的 Discord 以获取最新信息。

常见问题 (FAQ)

Prisma ORM 的无 Rust 二进制版本Prisma ORM 6.16 版本起已可用于生产,以下是我们用户的一些常见问题:

没有 Rust 引擎,Prisma 的包大小缩小了多少,为什么这有助于冷启动?

当 Prisma 移除 Rust 二进制查询引擎后,包大小从大约14 MB(gzip 压缩后 7 MB)降至大约1.6 MB(gzip 压缩后 600 KB),减少了85% 到 90%

这个更小的包在无服务器和边缘环境中加载更快,例如 AWS LambdaCloudflare WorkersVercel Edge Functions

由于需要加载和初始化的代码更少,冷启动变得更快,内存使用也减少了。

与旧的 Rust 引擎相比,使用无 Rust 二进制的 Prisma ORM 查询速度有多快?

在内部基准测试中,无 Rust 二进制的 Prisma ORM,也称为查询编译器,带来了显著的性能提升:

  • 包含 25,000 条记录的 findMany185 毫秒提升到 55 毫秒(约快 3.4 倍
  • take = 2000 的 findMany6.6 毫秒提升到 3.1 毫秒(约快 2.1 倍
  • 复杂连接从207 毫秒提升到 130 毫秒(约快 1.6 倍

您可以在Rust 到 TypeScript 性能更新博客中阅读更多信息。

这些改进在大型或复杂查询上最为显著。

无 Rust 二进制的 Prisma ORM 能在 Cloudflare、Deno 和 Bun 等运行时中工作吗?

是的。由于 Prisma 的新引擎完全在 TypeScript 和 WebAssembly 中运行,它不再依赖于原生二进制文件。

您现在可以在支持 JavaScript 或 WASM 的环境中(例如 Cloudflare WorkersBunDeno)使用 Prisma。

要启用它,请使用新的 prisma-client 生成器并为您的数据库配置正确的驱动适配器,例如 PostgreSQL 的 @prisma/adapter-pg

有关设置说明,请参阅Prisma 客户端生成器文档

如果 Rust 已经很快了,为什么切换到 TypeScript 和 WebAssembly 会让 Prisma 更快?

Rust 是一种非常快的系统语言,但在旧的架构中,Prisma 必须在 Rust 和 JavaScript 之间序列化和反序列化数据。

这种跨语言通信增加了开销,特别是对于大型查询。

新的查询编译器在 TypeScript 和 WebAssembly 中运行,这消除了对序列化步骤的需求,从而实现了更快的查询执行。

您可以在从 Rust 到 TypeScript:Prisma ORM 的新篇章中了解更多关于这一变化的信息。

使用无 Rust 二进制的 Prisma ORM 需要进行哪些更改?

要迁移到新版本,请执行以下操作:

  1. 使用新的 prisma-client 生成器,并在您的 schema.prisma 文件中设置 engineType = "client"
  2. 删除 binaryTargets 配置(不再需要)。
  3. 安装适用于您数据库的相应驱动程序适配器,例如 PostgreSQL 的 @prisma/adapter-pg 或 SQLite 的 @prisma/adapter-sqlite
  4. 运行 npx prisma generate 以重新生成您的 Prisma Client。

您可以在无 Rust 二进制 ORM 的 Prisma 文档中查看完整的使用指南。

如果需要,我可以切换回 Rust 引擎吗?

是的。如果您遇到兼容性问题,可以通过使用 6.16.0 之前的旧 Prisma ORM 版本来暂时恢复到旧版 Rust 引擎。

但是,无 Rust 二进制引擎现在是默认设置,并且建议所有新项目都使用它。

迁移步骤和回退指南可在无 Rust Prisma ORM 生产发布博客中找到。

不要错过下一篇文章!

订阅 Prisma 新闻通讯

© . This site is unofficial and not affiliated with Prisma Data, Inc.