You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Drizzle ORM中MySQL decimal类型查询结果类型为string而非number的原因咨询

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

火山引擎 最新活动