news 2026/9/19 12:53:35

drizzle-kit 0.31.4 修复解析:`halfvec`、`bit`、`sparsevec` 类型生成 bug 与 pgvector 向量列支持详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
drizzle-kit 0.31.4 修复解析:`halfvec`、`bit`、`sparsevec` 类型生成 bug 与 pgvector 向量列支持详解

drizzle-kit 0.31.4 修复解析:halfvecbitsparsevec类型生成 bug 与 pgvector 向量列支持详解

【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm

drizzle-kit 0.31.4 是一个聚焦性的修复版本,其核心变更只有一条:修复了halfvecbitsparsevec三种 PostgreSQL 类型在 drizzle-kit 中的类型生成 bug。本文以该变更说明(changelogs/drizzle-kit/0.31.4.md)为骨架,结合 drizzle-orm、drizzle-kit 仓库源码,说明这几种类型在 schema 定义、introspect 逆向生成与 SQL 生成中的实际行为,以及升级 0.31.4 后如何在项目里正确使用它们。

变更概览:一条修复背后的三个类型

0.31.4 的 changelog 全文如下:

Fixedhalfvec,bitandsparsevectype generation bug in drizzle-kit

这句话描述的是三类来自 pgvector 及 PostgreSQL 内置位串类型的列类型:

  • halfvec:pgvector 提供的半精度浮点向量类型,使用 16 位浮点存储每个维度,用于在保证召回率的前提下大幅压缩向量占用的磁盘与内存空间;
  • sparsevec:pgvector 提供的稀疏向量类型,只存储非零维度及其值,适合高维但大多数维度为零的向量(例如 TF-IDF、词袋类特征);
  • bit:PostgreSQL 内置的定长位串类型,配合 pgvector 的bit_hamming_opsbit_jaccard_ops操作符类可做二进制向量的汉明距离、Jaccard 距离检索。

这三类类型都属于"非内建、依赖用户安装扩展才能使用"的类型,而 drizzle-kit 的 introspect(数据库结构逆向)流程此前在处理这类用户自定义类型时存在生成错误,0.31.4 正是针对这一问题的修复。

修复的核心:introspect 中对 USER-DEFINED 类型的判定

要理解这个 bug 的根因,需要看 drizzle-kit 逆向数据库结构时对列类型的分流逻辑。在 drizzle-kit/src/serializer/pgSerializer.ts 中,表列(第 1491-1498 行)与视图列(第 1786-1793 行)的类型归属使用了同一套判定:

type: // filter vectors, but in future we should filter any extension that was installed by user columnAdditionalDT === 'USER-DEFINED' && !['vector', 'geometry', 'halfvec', 'sparsevec', 'bit'].includes(enumType) ? enumType : columnTypeMapped,

从源码结构可以推断出 bug 的成因:当数据库中的列被 PostgreSQL 元数据标记为USER-DEFINED类型时,drizzle-kit 会优先把它当作用户自定义枚举类型(走enumType分支)写入生成的 schema;但对于halfvecsparsevecbit这类同样以自定义类型形态存在、实则是 pgvector 扩展类型或内置位串类型的列,这种误判会把它们错误地当作 enum 处理,导致 introspect 生成的 schema 类型不正确。代码注释也明确写着 "filter vectors, but in future we should filter any extension that was installed by user",说明该修复策略是:先对已知的扩展类型(vectorgeometryhalfvecsparsevecbit)做白名单排除,使其回落到columnTypeMapped分支,按原生类型名生成。

同时,drizzle-kit/src/sqlgenerator.ts 第 137-141 行将vectorgeometryhalfvecsparsevecbit一并收录进 PostgreSQL 原生类型白名单pgNativeTypes

'vector', 'geometry', 'halfvec', 'sparsevec', 'bit',

该白名单的用途在于:生成 SQL(push / generate / migrate)时,只有命中白名单的类型才不会被强制加 schema 前缀和双引号包裹。也就是说,halfvecsparsevecbit只有被识别为原生类型,才会以halfvec(768)bit(64)这种干净的形式出现在生成的 SQL 中,而不是被错误地引用为带引号的用户自定义类型。

三种类型在 drizzle-orm 中的 schema 定义方式

修复的前提是 drizzle-orm 早已为这三种类型提供了完整的一等公民 API,均位于 drizzle-orm/src/pg-core/columns/vector_extension/ 目录下,并在 drizzle-orm/src/pg-core/columns/index.ts 中统一导出。

halfvec:半精度向量列

halfvec的构造函数定义在 halfvec.ts,其列的数据类型为PgHalfVector,数据映射为number[],driver 参数为字符串。在 schema 中使用方式与vector完全一致:

import { pgTable, halfvec } from 'drizzle-orm/pg-core'; export const embeddings = pgTable('embeddings', { id: integer('id').primaryKey(), embedding: halfvec('embedding', { dimensions: 768 }), });

参数说明:

  • dimensions:必填,声明向量的维度数。pgvector 对halfvec的维度上限较vector更宽松(可到数千维),但 schema 声明时仍应明确给出,方便 drizzle-kit 生成准确的halfvec(768)DDL。

sparsevec:稀疏向量列

sparsevec的构造函数定义在 sparsevec.ts,存在重载签名以兼容"名称 + 维度配置"与"仅名称(使用默认维度 0)"两种调用形式。其数据映射同样为number[]

import { pgTable, sparsevec } from 'drizzle-orm/pg-core'; export const docs = pgTable('docs', { id: integer('id').primaryKey(), features: sparsevec('features', { dimensions: 4096 }), });

参数说明:

  • dimensions:声明稀疏向量的最大维度数。注意 pgvector 对sparsevec的维度限制取决于所用版本(早期版本限制为 1600,新版放宽),声明时应以实际安装的 pgvector 版本为准;
  • 稀疏向量的实际存储只会记录非零维度,因此即使维度声明很大,只要数据稀疏,存储成本依然可控。

bit:定长位串列

bit的构造函数定义在 bit.ts,同样支持带维度配置或不带的调用形式,数据映射为字符串位串:

import { pgTable, bit } from 'drizzle-orm/pg-core'; export const binaryVecs = pgTable('binary_vecs', { id: integer('id').primaryKey(), code: bit('code', { dimensions: 64 }), });

参数说明:

  • dimensions:位串长度,声明后生成的 DDL 为bit(64);若不声明,则为无约束的bit
  • 位串类型常配合 pgvector 的bit_hamming_ops(汉明距离)与bit_jaccard_ops(Jaccard 距离)操作符类建立索引,用于二进制哈希向量的近邻检索。

三类类型可用的操作符类

drizzle-kit/src/extensions/vector.ts 中集中维护了 drizzle-kit 认可的向量扩展操作符类:

export const vectorOps = [ 'vector_l2_ops', 'vector_ip_ops', 'vector_cosine_ops', 'vector_l1_ops', 'bit_hamming_ops', 'bit_jaccard_ops', 'halfvec_l2_ops', 'sparsevec_l2_ops', ];

从中可以确认:

  • halfvec支持halfvec_l2_ops(L2 距离索引);
  • sparsevec支持sparsevec_l2_ops(L2 距离索引);
  • bit支持bit_hamming_opsbit_jaccard_ops

也就是说,在 drizzle-kit 0.31.4 中,这三类列不仅能被正确 introspect 和生成类型,还能在 drizzle-orm/src/pg-core/indexes.ts 对应的索引语法中被正确识别,例如:

import { pgTable, halfvec, index } from 'drizzle-orm/pg-core'; export const embeddings = pgTable('embeddings', { id: integer('id').primaryKey(), embedding: halfvec('embedding', { dimensions: 768 }), }, (t) => [ index('embedding_idx').using('hnsw', t.embedding.op('halfvec_l2_ops')), ]);

该修复覆盖的完整工作流

结合源码可以确认,0.31.4 的修复贯穿 drizzle-kit 的三条主链路:

  1. introspect 逆向drizzle-kit introspect读取数据库元数据时,halfvecsparsevecbit不再被误判为自定义枚举类型,而是生成正确的列类型(见 pgSerializer.ts 表列与视图列两处分流);
  2. SQL 生成:push / generate / migrate 生成 DDL 时,这三类类型命中pgNativeTypes白名单(sqlgenerator.ts),以无引号、无 schema 前缀的原生类型形式输出;
  3. schema 定义:配合 drizzle-orm 侧halfvecsparsevecbit列构造器(vector_extension),开发者手写 schema 与数据库结构保持一致。

升级到 drizzle-kit 0.31.4 后,建议回归验证一次针对 pgvector 相关表的 introspect 与 generate 流程,确认生成的列类型与索引操作符类符合预期。需要说明的是:这三类类型均依赖 PostgreSQL 侧安装对应扩展(pgvector 提供halfvecsparsevecbit的操作符类,bit本身是 PostgreSQL 内置类型),drizzle-kit 只负责在 ORM 与迁移层正确表达它们,扩展的安装仍需在数据库层面完成。

【免费下载链接】drizzle-ormORM项目地址: https://gitcode.com/gh_mirrors/dr/drizzle-orm

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 12:53:22

BrewUI:给Homebrew套上图形化界面,让软件包管理告别命令行

1. 先说结论:BrewUI 到底是个什么东西如果你在 macOS 或者 Linux 上折腾过开发环境,几乎不可能没听过brew这条命令。它就是 Homebrew,一个用命令行来管理软件包的工具。可恰恰是这个"命令行"三个字,把大量想入门的开发者…

作者头像 李华
网站建设 2026/9/19 12:53:18

11款笔记软件深度横评:Obsidian、Typora、Notion怎么选?

最近总有朋友问我同一个问题:市面上笔记软件这么多,到底该用哪一款?我的电脑里装了一圈,从 Notion 到 Obsidian,从 Typora 到 AFFiNE,最后发现一个残酷的事实——没有完美的笔记工具,只有适不适…

作者头像 李华
网站建设 2026/9/19 12:52:13

Unity Spine动画控制全指南:播放、回调与停止的工程技术实践

我用Spine做角色战斗表现时,最开始把伤害结算写在Update里靠播放时间硬算,结果策划一改动画时长,满屏伤害数字错位。后来彻底把播放、回调、停止这三件事重新理了一遍,才算把这套动画系统真正管住。这篇就把我在Unity里控制Spine动…

作者头像 李华
网站建设 2026/9/19 12:48:48

BrewUI:给 Homebrew 套上图形界面的包管理利器

1. BrewUI 是什么,为什么值得聊1.1 从 Homebrew 的生态现状说起每个用 macOS 做开发的程序员,早晚都会认识 Homebrew。它是一个包管理器,负责帮你安装、升级、卸载各种开源软件和开发工具。Git、Node、Python、Redis、FFmpeg,几乎…

作者头像 李华