资讯动态

drizzle-arktype:从 Drizzle ORM Schema 自动生成 ArkType 校验 Schema 的完整实战指南

发布时间:2026/9/19 10:06:41 来源:尧图企业网站定制
drizzle-arktype从 Drizzle ORM Schema 自动生成 ArkType 校验 Schema 的完整实战指南【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm导读drizzle-arktype是 Drizzle ORM 官方仓库中内置的集成插件它能够把你在drizzle-orm中定义的表Table、视图View与枚举Enumschema直接转换为 ArkType 类型系统下的运行时校验 Schema从而以一套 schema 同时驱动数据库建表与 API 请求/响应校验。阅读本文后你将掌握createInsertSchema、createUpdateSchema、createSelectSchema三个核心 API 的完整用法理解字段覆盖override与精炼refine两种定制手段并能从源码层面看懂不同数据库方言、不同列类型的映射规则与空值语义。本文以 changelogs/drizzle-arktype/0.1.2.md 的发布说明与使用文档为主体结合 drizzle-arktype 包内源码、测试用例展开讲解面向已经使用 Drizzle ORM、希望在服务端/客户端获得强类型数据校验的开发者。一、drizzle-arktype 是什么与 Drizzle 共生的 Schema 生成器drizzle-arktype是 Drizzle ORM 的官方插件核心定位是从 Drizzle ORM schema 生成 ArkType schema。你只需要在 Drizzle 中定义一次数据库结构插件就会在编译期推导出对应的 ArkType 类型并在运行时生成可用的校验器。根据官方发布说明插件提供以下能力见 drizzle-arktype/README.mdselect schema为表table、视图view和枚举enum生成读取场景的校验 Schemainsert / update schema为表生成写入场景的校验 Schema自动处理主键、默认值、生成列等语义全方言支持PostgreSQL、MySQL、SQLite从源码看还覆盖了 SingleStore见下文。drizzle-arktype在仓库中与 drizzle-zod、drizzle-valibot、drizzle-typebox 并列为 Drizzle 官方的schema 校验插件家族只是各自面向不同的校验库生态。它的入口文件 drizzle-arktype/src/index.ts 对外导出了createInsertSchema、createUpdateSchema、createSelectSchema等全部核心 API。二、快速开始三行代码生成三类 Schema安装依赖与 Drizzle ORM 配套使用pnpm add drizzle-orm arktype drizzle-arktype下面用发布说明中的标准示例演示完整用法changelogs/drizzle-arktype/0.1.2.mdimport { pgEnum, pgTable, serial, text, timestamp } from drizzle-orm/pg-core; import { createInsertSchema, createSelectSchema } from drizzle-arktype; import { type } from arktype; const users pgTable(users, { id: serial(id).primaryKey(), name: text(name).notNull(), email: text(email).notNull(), role: text(role, { enum: [admin, user] }).notNull(), createdAt: timestamp(created_at).notNull().defaultNow(), }); // Schema for inserting a user - can be used to validate API requests const insertUserSchema createInsertSchema(users); // Schema for updating a user - can be used to validate API requests const updateUserSchema createUpdateSchema(users); // Schema for selecting a user - can be used to validate API responses const selectUserSchema createSelectSchema(users); // Usage const isUserValid parse(insertUserSchema, { name: John Doe, email: johndoetest.com, role: admin, });三个 API 的职责分工非常清晰API适用对象典型场景createSelectSchema表、视图、枚举校验 API 响应数据、查询结果createInsertSchema表校验插入请求体创建createUpdateSchema表校验更新请求体部分更新上述示例中createUpdateSchema需要从drizzle-arktype导入与createInsertSchema、createSelectSchema同源均定义在 drizzle-arktype/src/schema.ts 中。2.1 枚举与视图同样可以生成 select schemacreateSelectSchema的重载签名见 drizzle-arktype/src/schema.types.ts同时接受表、视图与PgEnum。当传入pgEnum时返回的是type.enumerated(...enumValues)当传入视图时插件会通过getViewSelectedFields取出视图的投影字段。底层实现位于 drizzle-arktype/src/schema.tsexport const createSelectSchema ((entity, refine?) { if (isPgEnum(entity)) { return type.enumerated(...entity.enumValues); } const columns getColumns(entity); return handleColumns(columns, refine ?? {}, { never: () false, optional: () false, nullable: (column) !column.notNull, }) as any; }) as CreateSelectSchema;三、字段覆盖Override精确控制单个字段的类型生成结果往往需要与业务规则对齐。插件允许在第二个参数中传入一个精炼对象refine直接替换某个字段的 ArkType 类型// Overriding the fields const insertUserSchema createInsertSchema(users, { role: type(string), });上面的写法会把role字段从原来的admin | user枚举联合放宽为任意string。这在很多场景下都很有用例如前端表单允许用户自由输入角色文本由后端再做进一步权限判断。注意直接传入一个 ArkType 类型对象如type(string)、type.string.pipe(Number)表示整体替换该字段而传入一个函数则表示在插件生成的类型基础上精炼见下一节。测试 drizzle-arktype/tests/pg.test.ts 中验证了c3: type.string.pipe(Number)这样的整字段替换会直接生效且类型层面ExpectEqual...与运行时 shape 双重吻合。四、字段精炼Refine在生成类型之上叠加约束与直接覆盖不同精炼函数接收插件生成的类型并返回加工后的新类型。发布说明中的示例将id限制为至少 1// Refining the fields - useful if you want to change the fields before // they become nullable/optional in the final schema const insertUserSchema createInsertSchema(users, { id: (schema) schema.atLeast(1), role: type(string), });为什么要强调在字段变成 nullable/optional之前精炼因为handleColumns的执行顺序是先取列对应的基础类型 → 应用精炼函数typeof refinement function ? refinement(schema) : schema→ 最后才根据条件追加.or(type.null)与.optional()。这段逻辑位于 drizzle-arktype/src/schema.ts因此精炼函数里拿到的schema还是纯净的列类型不会受空值修饰符干扰。测试用例 drizzle-arktype/tests/pg.test.ts 展示了精炼后的字段仍会正确带上.optional()修饰。4.1 嵌套精炼与未知键保护对于视图尤其是通过 query builder 构造、包含嵌套选择对象或整表投影的视图精炼对象支持按嵌套结构逐层定制例如createSelectSchema(view, { nested: { c5: (schema) schema.atMost(1000), c6: type.string.pipe(Number), }, table: { c2: (schema) schema.atMost(1000), }, });测试 drizzle-arktype/tests/pg.test.ts 完整验证了嵌套精炼的运行时行为。与此同时插件提供了严格的类型保护精炼对象中如果出现表中不存在的键会触发编译期错误。其实现是NoUnknownKeys类型工具drizzle-arktype/src/schema.types.internal.ts对未知键生成DrizzleTypeErrorFound unknown key in refinement: ...测试文件里用// ts-expect-error显式断言了这种报错见 drizzle-arktype/tests/pg.test.ts。五、空值与可选性三种 Schema 的语义差异源码级解读这是drizzle-arktype最值得理解的部分同一个表select / insert / update 生成的字段修饰符完全不同。核心由Conditions接口的三个谓词控制drizzle-arktype/src/schema.types.internal.ts谓词selectinsertupdatenever字段被排除恒为false全部保留排除generatedAlwaysAs与generatedAlwaysAsIdentity列同 insertoptional字段变为可选恒为false全部必填非 notNull 列或notNull 且有默认值的列恒为true全部可选nullable字段可接受 null!column.notNull!column.notNull!column.notNull对应实现见 drizzle-arktype/src/schema.ts而类型层面的等价逻辑HandleSelectColumn/HandleInsertColumn/HandleUpdateColumn位于 drizzle-arktype/src/column.types.ts。以serial主键列为例select schemaid是必填的整数序列列视为非空insert schemaid字段会被排除属于生成列这正是插入时数据库自动生成主键的语义带默认值的列如createdAt的defaultNow()则变为可选update schema所有字段可选只有非空且无默认值的列在未提供时可能报错。测试 drizzle-arktype/tests/pg.test.ts 用 7 种列可空、非空、带默认、非空带默认、生成列、identity 列穷举验证了 insert / update 场景的完整结果是最直观的行为规范。六、数据类型映射从 Drizzle 列到 ArkType 类型columnToSchemadrizzle-arktype/src/column.ts负责把每种 Drizzle 列映射为 ArkType 类型映射优先级为枚举列 → 特殊类型geometry / point / vector / line / array 等→ 通用数据类型。下表整理了主要映射规则细节可在 drizzle-arktype/src/column.ts 与 drizzle-arktype/src/constants.ts 中核对Drizzle 列类型生成的 ArkType Schema说明text(x, { enum: [...] })/pgEnum列type.enumerated(...)枚举值直接映射为字面量联合integer/serial/int整数 范围限制按类型映射到 INT8/16/24/32/48 区间见numberColumnToSchemabigint({ mode: number })安全整数范围Number.MIN_SAFE_INTEGER~MAX_SAFE_INTEGERbigint({ mode: bigint })type.bigint.narrow(bigintNarrow)校验 INT64 边界见 drizzle-arktype/src/column.tsvarchar({ length })type.string.atMostLength(length)上限长度约束char({ length })type.string.exactlyLength(length)定长约束uuid正则校验RFC-4122 格式正则describe(a RFC-4122-compliant UUID)timestamp({ mode: date })/datetype.Date字符串模式则映射为type.stringjson/jsonbjsonSchema字面量 / 数组 / 对象的联合见 drizzle-arktype/src/column.tsinteger().array().array()多维数组按层递归指定维度时加exactlyLengthvector/halfvectype.number.array()声明了dimensions时附加exactlyLength(dimensions)geometry(point, tuple)/point(tuple)type([number, number])元组模式geometry(point, xy)/point(xy){ x: number, y: number }对象模式line(tuple)/line(abc)[number, number, number]/{ a, b, c }两种线模式customType/ 未知类型type.unknown兜底可通过精炼覆盖Buffer列bufferSchemainstanceof Buffer窄化数值范围常量集中定义在 drizzle-arktype/src/constants.ts如INT32_MIN -2147483648、INT32_UNSIGNED_MAX 4294967295numberColumnToSchema还针对 MySQL / SingleStore 的unsigned属性动态切换范围并对MySqlYear施加 1901–2155 的特殊区间。PostgreSQL 全量类型含bit、inet、macaddr、sparsevec等 30 余种的映射结果在 drizzle-arktype/tests/pg.test.ts 的all data types测试中逐列断言。七、类型安全的实现原理编译期推导管线drizzle-arktype的类型安全不仅体现在运行时校验更体现在编译期推导。整体推导管线drizzle-arktype/src/schema.types.internal.ts大致为BuildSchema遍历表的所有列用ColumnIsGeneratedAlwaysAs剔除生成列对每个列调用HandleColumn或HandleRefinement计算最终类型HandleColumn按 select / insert / update 三种模式注入 nullable / optional 修饰drizzle-arktype/src/column.types.tsHandleRefinement当用户提供精炼函数时将函数的返回类型再套上 nullable / optional 修饰NoUnknownKeys对精炼对象做键名校验未知键直接编译报错。由此生成的结果类型通过type.instantiate构造并与运行时handleColumns生成的 ArkType 对象保持严格一致。测试工具expectSchemaShapedrizzle-arktype/tests/utils.ts同时比对.json与.expression再配合ExpectEqual...做类型级断言双管齐下保证编译期类型 运行时行为。类型级 JSON 列的推导则由GetArktypeTypedrizzle-arktype/src/column.types.ts处理它会读取$type泛型参数例如对json().$typeTopLevelCondition()生成精确的TypeTopLevelCondition测试见 drizzle-arktype/tests/pg.test.ts。八、方言与测试覆盖插件宣称支持所有主流方言源码中columnToSchema的分支同时处理了pg-core、mysql-core、sqlite-core与singlestore-core的列类型见 drizzle-arktype/src/column.ts 的 import 列表且每个方言都有独立的端到端测试PostgreSQLdrizzle-arktype/tests/pg.test.ts含pgSchema、物化视图、嵌套视图等场景MySQLdrizzle-arktype/tests/mysql.test.tsSQLitedrizzle-arktype/tests/sqlite.test.tsSingleStoredrizzle-arktype/tests/singlestore.test.ts九、版本演进记录drizzle-arktype0.1.2 是携带完整使用文档的正式版本随后的 0.1.3changelogs/drizzle-arktype/0.1.3.md修复了两个关键问题TS language server 性能优化降低大规模类型推导对编辑器语言服务的开销修复 Vite 客户端环境下Buffer is not definedbufferSchema中instanceof Buffer的引用在浏览器端会抛出 ReferenceError相关 issue 为 drizzle-team/drizzle-orm#4383 与 #4371。如果你在 Vite / 纯浏览器端使用该插件且遇到Buffer相关报错升级到 0.1.3 即可。这也提醒我们在服务端与客户端共用校验 schema 时需要留意 Node 内置对象与浏览器环境的差异。十、典型应用模式与建议将上面的能力组合起来一个贴近生产实践的用法是单一数据源、三套视图用drizzle-orm定义全部表结构唯一事实来源用createInsertSchema生成创建接口的请求体验证器用createUpdateSchema生成PATCH 风格部分更新的验证器用createSelectSchema生成响应体的验证器可配合精炼对id、createdAt等服务端生成字段做额外约束。在编写精炼逻辑时记住两条铁律需要完全替换字段类型时传 ArkType 类型对象需要基于生成类型叠加约束时传函数并且函数形式的精炼发生在 nullable / optional 修饰之前因此可以放心地做atLeast、atMost、exactlyLength等约束而不用担心与空值修饰冲突。结语drizzle-arktype用一套 Drizzle schema 同时解决建表与数据校验两个问题消除了传统项目中手写两套 schema 导致的漂移风险。通过本文对 drizzle-arktype/src/schema.ts、drizzle-arktype/src/column.ts 等源码与测试用例的拆解可以看到它在 select / insert / update 语义、数值范围、字符串长度、JSON 与向量类型等方面都做了严谨的映射并且具备编译期类型级防护。对于追求类型安全与开发效率的 Drizzle 用户这是一个开箱即用的高质量补充。【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价