Drizzle ORM中MySQL decimal类型查询结果类型为string而非number的原因咨询
你好呀!我最近在使用Drizzle ORM操作MySQL数据库时遇到了一个困惑,想跟大家请教下:
我定义的表结构是这样的:
export const myTable = mysqlTable( "MyTable", { id: varchar("id", { length: 191 }).notNull(), value: decimal("value", { precision: 7, scale: 4 }).notNull(), createdAt: datetime("createdAt", { mode: "date" }) .default(sql`CURRENT_TIMESTAMP`) .notNull(), }, (table) => { return { myTableId: primaryKey(table.id), }; } );
然后查询代码是:
type MyTable = InferModel<typeof myTable, "select">; const values: MyTable[] = await db.select().from(myTable);
我发现values[0].value的类型是string,但我原本以为应该是number类型。我翻遍了Drizzle的文档、GitHub Issues和StackOverflow都没找到相关说明,想搞清楚这到底是为什么,或者是不是我哪里配置错了?
后来我自己摸索出了一个“修复”类型的方法,但还是没搞懂为什么double类型返回的是number,而decimal返回的是string,不过暂时能用就行。
另外感谢@ColouredPanda和@andrew-allen的提示,现在我大概明白背后的原因了:
其实这是因为JavaScript的number类型是基于IEEE 754标准的浮点数,没办法精确表示所有的decimal类型数值——尤其是当decimal的精度较高时,直接转成number会出现精度丢失的问题。Drizzle ORM为了保证数值的精确性,就把decimal类型的查询结果默认设为string类型,这样就能完整保留原始数值的精度。
而double类型本身就是MySQL里的浮点数类型,和JavaScript的number类型的存储机制更匹配,所以直接映射成number类型也不会有太大精度问题,因此Drizzle就把它映射成了number。
如果你确实需要把decimal类型转成number,也可以自己手动处理,比如用Number(values[0].value)来转换,但要注意如果数值精度超出了number的表示范围,可能会出现精度丢失的情况哦。
备注:内容来源于stack exchange,提问作者Alan Sikora




