Drizzle ORM 0.45.3 新特性:Netlify DB 驱动完整接入指南
【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm
本文基于 changelogs/drizzle-orm/0.45.3.md 整理。Drizzle ORM 0.45.3 正式引入由 Netlify 团队开发维护的Netlify DB Driver,让你可以在 Netlify 平台生态中,以零配置或显式客户端的方式直接使用 Drizzle 的类型安全查询能力。读完本文,你将掌握该驱动的安装方式、三种初始化写法、底层架构原理(HTTP 查询 + WebSocket 事务)以及迁移与缓存等进阶用法。
一、Netlify DB Driver 是什么
Netlify DB 是 Netlify 平台提供的关系型数据库服务(基于 PostgreSQL 协议)。在 Drizzle ORM 0.45.3 之前,在 Netlify 环境中使用 Drizzle 需要手动挑选底层驱动(如@neondatabase/serverless、node-postgres等)并处理连接配置;0.45.3 新增的drizzle-orm/netlify-db入口则是专门为 Netlify DB 定制的适配层。
该驱动由Netlify 团队开发与维护(原 changelog 明确标注),Drizzle 侧负责将其接入PgDialect与PgDatabase体系,从而让db.select()、db.insert()、关系查询、迁移等 Drizzle 能力在 Netlify DB 上开箱即用。
二、安装
驱动本体以可选 peer dependency 的形式声明在 drizzle-orm/package.json 中("@netlify/db": ">=0.4.0",且标记为optional),因此只需显式安装客户端包即可:
npm i @netlify/db如果使用 pnpm 或 yarn,命令等价替换为pnpm add @netlify/db/yarn add @netlify/db。安装完成后即可从drizzle-orm/netlify-db子路径导入。
三、三种初始化方式(用法示例)
原 changelog 给出了三种典型写法,这里逐一展开并补充参数细节。
3.1 零配置模式(推荐,读取环境变量)
import { drizzle } from 'drizzle-orm/netlify-db'; // 自动读取 NETLIFY_DB_URL 与 NETLIFY_DB_DRIVER 环境变量 const db = drizzle(); const result = await db.execute('select 1');这是 Netlify 平台上的首选用法:驱动内部调用@netlify/db的getDatabase()(见 driver.ts)来读取环境变量并解析出连接。从源码结构看,getDatabase()返回的连接对象带有driver字段:
- 当
driver === 'serverless'时,走 HTTP 客户端(httpClient+Pool)构建NetlifyDbDatabase; - 当
driver === 'server'时,会直接委托给 node-postgres 适配层构建NodePgDatabase(见 driver.ts)。
也就是说,Drizzle 会根据NETLIFY_DB_DRIVER指示的连接形态自动选择 HTTP 无状态查询或服务端长连接,对使用者完全透明。
3.2 显式传入连接字符串
import { drizzle } from 'drizzle-orm/netlify-db'; const db = drizzle(process.env.DATABASE_URL); const result = await db.execute('select 1');适用于连接信息不在NETLIFY_DB_*环境变量中的场景。源码中当第一个参数是字符串时,会执行neon(connectionString)创建 HTTP 客户端、new Pool({ connectionString })创建连接池,再统一走construct()构建数据库实例(driver.ts),底层复用@neondatabase/serverless驱动。
3.3 显式客户端(由消费者控制驱动)
import { drizzle } from 'drizzle-orm/netlify-db'; // Explicit client — 连接管理与驱动选择完全由你掌控 const db = drizzle({ client: netlifyDbClient }); const result = await db.execute('select 1');适合需要自定义连接池、HTTP 客户端实例(例如注入代理、自定义 fetch 或复用已有连接)的高级场景。client支持两种形态(见 driver.ts 中的DrizzleClient类型):
{ driver: 'serverless', httpClient, pool, connectionString }:构建基于 HTTP 的NetlifyDbDatabase;{ driver: 'server', pool, connectionString }:构建基于 node-postgres 的NodePgDatabase。
此外,配置对象写法还支持connection字段(字符串或{ connectionString }),等价于 3.2 的字符串传参(driver.ts)。
四、源码级原理:HTTP 查询与 WebSocket 事务
Netlify DB 驱动的实现分为四个文件(drizzle-orm/src/netlify-db/):
driver.ts:drizzle()入口工厂、NetlifyDbDriver、NetlifyDbDatabase;session.ts:NetlifyDbSession、NetlifyDbWsSession、NetlifyDbTransaction;migrator.ts:migrate()迁移执行器;index.ts:仅导出 driver 与 session 的公共 API。
4.1 常规查询走 HTTP(无状态、无冷启动成本)
NetlifyDbSession继承自PgSession,其prepareQuery()复用NeonHttpPreparedQuery(session.ts),普通select/insert/update/delete都以 HTTP 请求方式发送,天然契合无服务器函数按需伸缩的特性。db.execute()与db.queryObjects()内部也通过clientQuery以arrayMode: true+fullResults: true执行。
4.2 事务走 WebSocket 连接
事务需要跨多条语句保持同一会话状态,因此NetlifyDbSession.transaction()会通过pool.connect()取出一个连接,构建NetlifyDbWsSession并在其上执行begin→ 回调 →commit/rollback,结束后释放连接(session.ts)。该会话使用NeonPreparedQuery并通过 WebSocket 与数据库通信——这正是 session.ts 中ensureWebSocket()函数存在的意义:为neonConfig.webSocketConstructor显式注入全局WebSocket,保证无服务器运行时也能建立 WebSocket 事务通道。
4.3 嵌套事务使用 Savepoint
NetlifyDbTransaction覆写了transaction()方法:嵌套事务通过savepoint spN/release savepoint spN/rollback to savepoint spN实现(session.ts),与外层 WebSocket 事务共用同一条连接,保证嵌套事务的原子性与隔离语义。
4.4 批量操作与类型映射
batch():将多条语句先分别构建为 HTTP 查询,再通过httpClient.transaction()一次性提交并映射结果(session.ts);- 时间类型处理:
NetlifyDbDriver.initMappers()对TIMESTAMPTZ、TIMESTAMP、DATE、INTERVAL及数组类型(OID 1231/1115/1185/1187/1182)注册了保持原字符串的 parser(driver.ts),避免时间类型在序列化传输中失真。
五、配置项:logger 与 cache
drizzle()的第二个参数(或配置对象)支持DrizzleConfig,当前驱动可用的核心选项(见 driver.ts):
| 配置项 | 类型 | 说明 |
|---|---|---|
logger | boolean \| Logger | true时使用DefaultLogger打印 SQL 与参数;传自定义Logger可实现埋点/日志收集;默认不输出 |
casing | 'snake_case'等 | 传入PgDialect,控制列名大小写映射 |
schema | Drizzle schema 对象 | 启用关系查询(db.query),内部通过extractTablesRelationalConfig构建关系配置 |
cache | Cache | 查询缓存;启用后实例上会暴露$cache,并在写操作时调用cache.onMutate做失效处理 |
例如:
import { drizzle } from 'drizzle-orm/netlify-db'; import * as schema from './schema'; const db = drizzle({ schema, logger: true, // 打开 SQL 日志 }); const result = await db.query.users.findMany(); // 关系查询另外,drizzle.mock()(见 driver.ts)可用于单元测试中构造不发起真实连接的数据库实例,便于对业务代码做隔离测试。
六、数据库迁移(migrate)
迁移入口从drizzle-orm/netlify-db/migrator导入:
import { drizzle } from 'drizzle-orm/netlify-db'; import { migrate } from 'drizzle-orm/netlify-db/migrator'; const db = drizzle(); await migrate(db, { migrationsFolder: './drizzle' });MigrationConfig支持三个字段(见 migrator.ts):
migrationsFolder:必填,drizzle-kit 生成的迁移目录;migrationsTable:可选,自定义迁移记录表名(默认__drizzle_migrations);migrationsSchema:可选,自定义迁移记录所在的 schema(默认drizzle)。
netlify-db/migrator.ts 的实现逻辑是:若传入的是NodePgDatabase实例则委托给 node-postgres 迁移器;否则通过readMigrationFiles读取meta/_journal.json与对应的 SQL 文件,再交给PgDialect.migrate按 journal 顺序执行(含--> statement-breakpoint语句切分与 sha256 校验)。
上述自定义 schema / 自定义表的用法均有集成测试覆盖,可参考 integration-tests/tests/pg/netlify-db.test.ts 中migrator : migrate with custom schema、migrator : migrate with custom table等用例。
七、从 changelog 到源码的验证小结
- 版本号与依赖声明一致:drizzle-orm/package.json 中
drizzle-orm版本为0.45.3,且声明了可选 peer 依赖@netlify/db >= 0.4.0; - 三种初始化写法(零配置 / 连接串 / 显式 client)均有对应重载与实现(driver.ts);
- HTTP 常规查询 + WebSocket 事务 + Savepoint 嵌套事务的完整链路可在 session.ts 中逐行验证;
- 真实可用性由 integration-tests/tests/pg/netlify-db.test.ts 保障(测试通过
NETLIFY_DB_URL环境变量连接真实数据库,覆盖迁移、时间类型映射、db.execute等场景)。
八、注意事项
- Netlify DB 驱动由 Netlify 团队维护,升级时建议关注其独立发布节奏与版本兼容性;
- 零配置模式依赖
NETLIFY_DB_URL与NETLIFY_DB_DRIVER环境变量,本地开发时若未配置会无法连接,可改用 3.2/3.3 的显式传参方式; - 常规查询走 HTTP,事务走 WebSocket,因此运行环境(Node.js ≥ 20 等)需提供全局
WebSocket实现,否则事务会失败(源码已做自动注入兜底); - 若要使用关系查询(
db.query),记得在配置中传入schema。
九、结语
Drizzle ORM 0.45.3 的 Netlify DB Driver 把 Netlify 平台的数据库服务无缝接入了 Drizzle 的类型安全 ORM 体系:一行drizzle()即可零配置启动,底层自动在 HTTP 无状态查询与 WebSocket 事务之间切换,并完整保留 Drizzle 的迁移、批量、缓存与关系查询能力。结合上文源码分析,你可以放心地在 Netlify Functions / Edge 场景中使用它,也可以在需要精细控制时通过显式 client 接管连接生命周期。
【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考