Prisma Bun 适应器
使用 Prisma 7. 0 到 1.3 版本
用于 Bun 本地 SQL 客户端的 Prisma 驱动程序适配器(PostgreSQL, MySQL, SQLite).
- Bun 备份连接的外部运行时间依赖性为零
- 基于模板字符串的参数化
- 与 Prisma 6 驱动适配器 API 合作
安装
选择您想要的适配器 。 该套装包括所有3名车手的课.
bun add @abcx3/prisma-bun-adapter
可选性( 用于此 repo 中的比较/ 测试):
bun add -d @prisma/adapter-pg @prisma/adapter-planetscale mysql2 better-sqlite3
快速启动
PostgreSQL (本族语言):
import { PrismaClient } from "@prisma/client";
import { BunPostgresAdapter } from "@abcx3/prisma-bun-adapter";
const adapter = new BunPostgresAdapter({
connectionString: process.env.DATABASE_URL!,
maxConnections: 20,
});
const prisma = new PrismaClient({
adapter: adapter,
log: ["query", "info", "warn", "error"],
});
await prisma.user.findMany();
优化构建( 可选)
请注意,优化后的软件包只与PostgreSQL合作. 未来可能会增加 MySQL 支持 .
包裹还装有"最优化"的包裹 @abcx3/prisma-bun-adapter/optimized。它允许一些额外的运行时间调试:连接集合(默认) maxConnections: 20),热切地热身了"Postgres"套接字,更具有攻击性的SQL模板缓存. 这些功能提高了高通币应用程序的吞吐量,但增加了一些启动工作和内存使用.
您可以明确选择:
import { PrismaClient } from "@prisma/client";
import { BunPostgresAdapter } from "@abcx3/prisma-bun-adapter/optimized";
const adapter = new BunPostgresAdapter({
connectionString: process.env.DATABASE_URL!,
maxConnections: 20,
});
const prisma = new PrismaClient({ adapter });
await prisma.user.findMany();
如果您更愿意在无法使用优化捆绑时自动掉回( 例如, 在不运出额外捆绑的微小部署中), 将 require 尝试/捕获并返回基地入口。 核心API和配置形状在两个构件之间相同,因此切换是一行变化.
运行时配置
适配器查看一些环境变量来控制集合行为:
| 新闻 var | 默认 | 它会做什么 |
|---|---|---|
PRISMA_BUN_ADAPTER_DISABLE_POOL | false | 何时 true,则完全禁用连接集,并为每个查询创建新的 Bun 连接. |
PRISMA_BUN_ADAPTER_DISABLE_POOL_FOR_TX | true | 禁用 Prisma 的集合 $transaction 只有电话。 虽然是真实的,但每个交互交易都得到一个专用的短寿命连接. |
构建选择(base vs 优化)是通过导入路径完成的,而不是通过环境变量完成的. 如果您想要在运行时加载您所要加载的闸门,请在主机应用程序代码(例如.
if (process.env.MY_FLAG) require("@abcx3/prisma-bun-adapter/optimized") else require("@abcx3/prisma-bun-adapter")) (中文(简体) ).
连接健康池管理
优化的适配器包括强有力的接通健康检查,以处理下列原因造成的间歇性接通问题:
- PostgreSQL 服务器闲置超时(
idle_session_timeout, (中文(简体) ),tcp_keepalives_*(中文(简体) ) - 网络防火墙丢弃闲置的 TCP 连接
- 数据库重新启动
配置选项
import { BunPostgresAdapter } from "@abcx3/prisma-bun-adapter/optimized";
const adapter = new BunPostgresAdapter({
connectionString: process.env.DATABASE_URL!,
maxConnections: 20,
// Connection validation settings (all optional)
validateOnBorrow: true, // Enable health checks (default: true)
validateIdleThresholdMs: 10000, // Only validate connections idle > 10s (default: 10000)
validationQuery: "SELECT 1", // Health check query (default: "SELECT 1")
maxAcquireRetries: 2, // Retry acquiring healthy connections (default: 2)
});
| 选项 | 默认 | 说明 |
|---|---|---|
validateOnBorrow | true | 启用时, 在从池中返回之前先验证连接 |
validateIdleThresholdMs | 10000 | 只有验证闲置时间超过此( ms) 的连接 。 避免最近使用的连接的验证间接费用 |
validationQuery | "SELECT 1" | 用于测试连接活度的轻量级查询 |
maxAcquireRetries | 2 | 在失败前重新尝试获得健康连接的次数 |
如何运作
-
智能验证: 连接只有在闲置时间超过
validateIdleThresholdMs。最近使用的连接跳过校验,以便更好的性能. -
自动删除:死亡连接自动被检测出,并从池中移除. 适配器跟踪每个连接的元数据,包括创建时间,上次使用时间,以及最后一次验证时间.
-
基于错误的删除:如果一个查询失败与连接相关出错(如"连接重置","socket hang up",来自 stale 连接的认证出错),则该连接被移除而不再返回池.
-
重试逻辑: 当获取连接时,适配器将重试至
maxAcquireRetries如果遇到已死亡的连接,则需要时间.
集合统计
您可以使用 getPoolStats() 驱动程序适配器上的方法 :
import { PrismaClient } from "@prisma/client";
import { BunPostgresAdapter, OptimizedBunPostgresDriverAdapter } from "@abcx3/prisma-bun-adapter/optimized";
const adapter = new BunPostgresAdapter({
connectionString: process.env.DATABASE_URL!,
});
const driver = await adapter.connect() as OptimizedBunPostgresDriverAdapter;
const prisma = new PrismaClient({ adapter: driver });
// Get pool statistics
const stats = driver.getPoolStats();
console.log(stats);
// {
// total: 5, // Total connections in pool
// idle: 3, // Available connections
// active: 2, // Connections in use
// waiting: 0, // Requests waiting for a connection
// deadConnectionsEvicted: 1, // Dead connections removed
// validationFailures: 1, // Failed health checks
// }
建议设置
对于大多数生产工作量:
const adapter = new BunPostgresAdapter({
connectionString: process.env.DATABASE_URL!,
maxConnections: 10, // Adjust based on your workload
validateOnBorrow: true, // Enable health checks
validateIdleThresholdMs: 10000, // 10 seconds - shorter than server timeout
});
如果您的 PostgreSQL 服务器有短句 idle_session_timeout (例如30秒),设定 validateIdleThresholdMs 以缩短(例如,5000ms)来捕捉断层连接,以免产生错误.
抬头: Bun的集合连接目前可能会在嵌入式的Prisma交易中出现错误(连接被重新使用太早,导致“交易已经关闭”错误)。 在该错误完全解决之前,优化适配器默认
PRISMA_BUN_ADAPTER_DISABLE_POOL_FOR_TX改为true; 保留它,除非您有本地固定,或者如果首选的话使用基准适配器.
导入矩阵
使用这些图案取决于您想要的构建模式和您的模块系统.
-
Base( 默认) 构建
- 无害环境管理:
import { BunPostgresAdapter, BunMySQLAdapter, BunSQLiteAdapter } from "@abcx3/prisma-bun-adapter"
- CJS: 贾克:
const { BunPostgresAdapter } = require("@abcx3/prisma-bun-adapter")
- 无害环境管理:
-
优化邮政建设( 子路径)
- 无害环境管理:
import { BunPostgresAdapter } from "@abcx3/prisma-bun-adapter/optimized"import BunPostgresAdapter from "@abcx3/prisma-bun-adapter/optimized"import { BunPostgres } from "@abcx3/prisma-bun-adapter/optimized"(别名)
- 根再出口( ESM) :
import { OptimizedBunPostgresAdapter } from "@abcx3/prisma-bun-adapter"import { BunPostgresOptimized } from "@abcx3/prisma-bun-adapter"- 高级( 司机类 ):
import { OptimizedBunPostgresDriverAdapter } from "@abcx3/prisma-bun-adapter"
- 无害环境管理:
TypeScript 模块分辨率提示( ESM 子路径)
当导入最优化的子路径时, 把这些设置在您的主机工程的 tsconfig.json数字 :
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext"
}
}
Node16 还行 这符合节点式的无害环境管理/CJS分辨率,并避免错误,如“在启用“允许导入TsExtensions”时,导入路径只能以'.ts'扩展来结束。”
使用像普通一样的 Prisma
这个适配器与Prisma的驱动适配器API相融合. 您继续使用 Prisma 客户端 完全相同 :
// Model delegates work unchanged
const users = await prisma.user.findMany({
where: { email: { contains: "@example.com" } },
include: { posts: true },
});
// Creates, updates, nested writes, include/select, aggregations, etc.
await prisma.post.create({
data: {
title: "Hello",
author: { connect: { id: 1 } },
},
});
// Interactive transactions work too
const created = await prisma.$transaction(async (tx) => {
const user = await tx.user.create({ data: { email: "[email protected]" } });
await tx.post.create({ data: { userId: user.id, title: "Welcome" } });
return user;
});
服务/DI用法(如雀巢JS):在Async工厂创建客户端并在需要时注入.
import { PrismaClient } from "@prisma/client";
import { BunPostgresAdapter } from "@abcx3/prisma-bun-adapter";
export async function makePrisma() {
const adapter = new BunPostgresAdapter(process.env.DATABASE_URL!);
return new PrismaClient({ adapter });
}
// elsewhere
const prismaService = await makePrisma();
const rows = await prismaService.user.findMany();
页:1
- 您使用 DB 密码时不需要%\\ 编码特殊字符
DATABASE_URL。适配器会自动将权限规范化并编码,这样模式查询就如prisma.user.findFirst工作,而不论密码内容. - 不需要重写查询: 继续使用
prisma.<model>.<method>和往常一样. - TypeScript 模块分辨率:如果您的主机项目使用 TypeScript 并导入优化后子路径(或依赖 HESM 子路径导出), 设置
compilerOptions.module财务报告和审定财务报表compilerOptions.moduleResolution改为"Node16"或者说"NodeNext"在你身边tsconfig.json此选项符合节点式的无害环境管理/CJS分辨率,并避免导入路径错误@abcx3/prisma-bun-adapter/optimized。 。 。 .
解决问题
-
第一次模式查询(例如,
user.findFirst: 这通常是指你的DATABASE_URL是不正确的(例如缺少方案/主机)或包含一个会打破 URL 的偏差字符。 适配器自定义编码证书,但如果解析仍然失败,验证URL形状有效(例如,postgresql://user:pass@host:5432/db?sslmode=disable) (中文(简体) ). -
无法访问的模型: 确保您运行
prisma generate更新您的计划后, 并构建PrismaClient与适配器厂,例如.new PrismaClient({ adapter: new BunPostgresAdapter(process.env.DATABASE_URL!) })产生示范代表(如:,prisma.user.findFirst与这个适配器正常工作. -
优化构建时键入脚本导入出错: 配置
tsconfig.json与module: "Node16" | "NodeNext"财务报告和审定财务报表moduleResolution: "Node16" | "NodeNext"示例:{ "compilerOptions": { "module": "NodeNext", "moduleResolution": "NodeNext" } }
MySQL (本族区):
import { PrismaClient } from "@prisma/client";
import { BunMySQLAdapter } from "@abcx3/prisma-bun-adapter";
const adapter = new BunMySQLAdapter(process.env.DATABASE_URL!);
const prisma = new PrismaClient({ adapter });
SQLite( Bun 本地语) :
import { PrismaClient } from "@prisma/client";
import { BunSQLiteAdapter } from "@abcx3/prisma-bun-adapter";
const adapter = new BunSQLiteAdapter(":memory:");
const prisma = new PrismaClient({ adapter });
占位符和参数化
- PostgreSQL: 支持
$1, $2, ...(首选),以及?为方便. - MySQL/SQLite: 使用
?占位符 .
实例:
// Postgres
await prisma.$queryRaw`SELECT $1 as value`;
// or
await prisma.$queryRaw({ sql: "SELECT $1 as value", args: [123] });
// MySQL / SQLite
await prisma.$queryRaw({ sql: "SELECT ? as value", args: [123] });
API 表面
该套件输出以下类别:
BunPostgresAdapterBunMySQLAdapterBunSQLiteAdapter
每个班都执行Prisma的 SqlDriverAdapter 盖子下的合同,可以传给 PrismaClient 通过 adapter 选项.
环境
- Bun 备份连接需要运行时间 .
- 当您在应用程序中使用 Prisma 客户端时, 节点被支持( 适配器仍然通过 Bun 的本地 SQL 在运行时间内运行) 。 在大多数项目中, 您将在 Bun 内运行您的 Prisma 客户端 .
- 建议的发动机:18号节点,1号机
测试和基准
所有测试和基准都是在多克中自动配置的,所以需要安装多克.
- 运行
tests:setup旋转测试数据库,初始化并用数据进行种子 - 运行
tests:run运行所有测试和基准 - 运行
tests:stop停止并删除数据库容器
您也可以进行任何单个测试/基准,以获得更多的颗粒性结果:
bun test:multibun test:comparisontest:comprehensivetest:performancetest:bench:prisma-complextest:bench:sql-complexdemo:sqlitedemo:quick
注: SQLite 比较现在使用 sql.js (网络大会)基线而不是 better-sqlite3,因为 Bun 目前装入本地模块时会崩溃。 倒置使演示可以直接运行在 Bun 下并包括一个小型模拟驱动机的起落架,这样的结果可以更紧密地匹配本地的Node.js适配器.
构建出版( 维护者) (P)
这个包裹船预建 JS和 .d.ts 类型 dist/。 。 。 .
脚本 :
bun prepublish-(或bun run build,将 TypeScript 编译为 javascript,并附带声明和输出到dist/bun run test:performance- 可选性能演示bun run test:comparison- 可选比较脚本bun run test:bench:prisma-complex- Prisma深度工作量(Bun vs PrismaPg)bun run test:bench:sql-complex- 复杂的生 SQL( Bun vs pg)
公布核对表:
- 更新版本编号
package.json。 。 。 . - 以新变化更新 ChangeGELOG.md
bun publish
财务问题
问:我明白了 syntax error at or near "as" 在邮局.
A: 使用 Postgres 风格的占位符($1, (中文(简体) ), $2,)或升级为接受两者的软件包版本 ? 财务报告和审定财务报表 $n。此软件包可适当转换占位符,用于 Bun 的 SQL 模板字符串.
问:我如何运行测试脚本?
答复:这些只用于制定地方基准。 见 test-app/setup-databases.md 用于设置 Postgres/ MySQL 容器,然后运行脚本 package.json。 。 。 .
基准结果
基准结果:
Bun PostgreSQL 页面存档备份,存于互联网档案馆 总时间:8.82米 每起攻击:0.09亿 行动/秒:11332
- Bun MySQL : (英语) 总时间:12.28米 任务:0.12米 行动/秒:8144
Bun SQLite 翻译: 总时间:1.76ms 任务:0.02ms 行动/秒:56723
传统 PostgreSQL (pg) : 总时间:16.38米 任务:0.16ms 行动/秒: 6106
传统 MySQL( Mysql2) : 总时间:19.41米 任务:0.19ms 行动/秒:5153
按数据库分列的性能比较:
后卫: Bun: 11332 ops/sec (0.09ms avg) (中文(简体) ) 传统:6106 ops/sec(0.16ms avg) QQ Bun 速度快 1.86x (1.86x 加速) Bun PostgreSQL:11332 行动/秒 * * * 传统邮报QL(pg):6106次行动/秒
- 盾 Bun: 8144 ops/sec (0.12ms avg) (英语) 传统:5153 ops/sec(0.19ms avg) QQ Bun 速度快 1.58x (1.58x 加速) Bun MySQL:8144 行动/秒 传统MySQL(mysql2):5153 ops/sec
SQLITE:只有一个适配器可用 Bun SQLite: 56723 行动/秒
总结:
Bun适配器平均值:25400 ops/sec * 传统适配器平均数:5629次操作/秒 Bun适配器平均速度为 4.51x
测试成功5个适配器
许可证
麻省理工学院 — 看 package.json#license。 。 。 .