英文:
Drizzle ORM - decimal MySQL is a string?
问题
以下是翻译好的部分:
// 导出模式:
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);
请注意,代码中的HTML实体字符(如"
)已被转换为相应的双引号。
英文:
The schema:
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),
};
}
);
The code:
type MyTable = InferModel<typeof myTable, "select">;
const values: MyTable[] = await db.select().from(myTable);
The type of values[0].value
is string
, and I figure it should be a number
.
I could not find anything related to this on Drizzle docs, Github Issues or StackOverflow, and I would like to understand why this happens, or, if I'm making any mistakes.
EDIT: I added an answer that "fixes" the type, but does not answer why double
becomes a number
and decimal
becomes a string
, which is enough for me.
EDIT 2: Thanks @ColouredPanda and @andrew-allen: https://github.com/drizzle-team/drizzle-orm/issues/570#issuecomment-1646033240
答案1
得分: 1
这可能不是关于“为什么小数变成字符串”的答案,但它解决了类型问题,这是我的主要关注点。
不要使用 decimal
,而是使用 double
。Drizzle 将自动将 double
推断为 number
。
更新后的架构:
export const myTable = mysqlTable(
"MyTable",
{
id: varchar("id", { length: 191 }).notNull(),
value: double("value", { precision: 7, scale: 4 }).notNull(),
createdAt: datetime("createdAt", { mode: "date" })
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),
},
(table) => {
return {
myTableId: primaryKey(table.id),
};
}
);
英文:
This might not be an answer to the "why decimals become strings", but it answers the typing problem, which was my main concern.
Instead of decimal
, use double
. Drizzle will automatically infer double
to number
.
The updated schema:
export const myTable = mysqlTable(
"MyTable",
{
id: varchar("id", { length: 191 }).notNull(),
value: double("value", { precision: 7, scale: 4 }).notNull(),
createdAt: datetime("createdAt", { mode: "date" })
.default(sql`CURRENT_TIMESTAMP`)
.notNull(),
},
(table) => {
return {
myTableId: primaryKey(table.id),
};
}
);
答案2
得分: 0
export const db = mysqlTable("someDb", {
weight: decimal("weight", {
precision: 6, scale: 2
}) as unknown as MySqlDoubleBuilderInitial<"weight">
});
用这种方式,我仍然可以使用 DECIMAL SQL 类型(这正是我想要的),并且 TypeScript 类型在我的整个代码库中都能正常工作(weight
是 number
类型)。
我认为这种类型断言是安全的,因为当我检查 typeof weight
时,它返回 number
,而且(我相信)JavaScript 数字支持我指定的精度。
英文:
What I've done to workaround this is adding type assertion like this:
export const db = mysqlTable("someDb", {
weight: decimal("weight", {
precision: 6, scale: 2
}) as unknown as MySqlDoubleBuilderInitial<"weight">
});
In this way, I still can use DECIMAL SQL type (which is what I really want) and typescript types works correctly in all my code base (weight is number
).
I think is safe to do this type assertion because when I check typeof weight
it returns "number"
and (I believe) that javascript number supports my specified precision
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论