51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Drizzle ORM – MySQL中的decimal是一个字符串吗?

英文:

Drizzle ORM - decimal MySQL is a string?

问题 {#heading}

以下是翻译好的部分:

// 导出模式:
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实体字符(如&quot;)已被转换为相应的双引号。 英文:

The schema:

export const myTable = mysqlTable(
  &quot;MyTable&quot;,
  {
    id: varchar(&quot;id&quot;, { length: 191 }).notNull(),
    value: decimal(&quot;value&quot;, { precision: 7, scale: 4 }).notNull(),
    createdAt: datetime(&quot;createdAt&quot;, { mode: &quot;date&quot; })
      .default(sql`CURRENT_TIMESTAMP`)
      .notNull(),
  },
  (table) =&gt; {
    return {
      myTableId: primaryKey(table.id),
    };
  }
);

The code:

type MyTable = InferModel&lt;typeof myTable, &quot;select&quot;&gt;;
`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}

得分: 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(
  &quot;MyTable&quot;,
  {
    id: varchar(&quot;id&quot;, { length: 191 }).notNull(),
    value: double(&quot;value&quot;, { precision: 7, scale: 4 }).notNull(),
    createdAt: datetime(&quot;createdAt&quot;, { mode: &quot;date&quot; })
      .default(sql`CURRENT_TIMESTAMP`)
      .notNull(),
  },
  (table) =&gt; {
    return {
      myTableId: primaryKey(table.id),
    };
  }
);

答案2 {#2}

得分: 0

export const db = mysqlTable("someDb", {
  weight: decimal("weight", {
    precision: 6, scale: 2
  }) as unknown as MySqlDoubleBuilderInitial<"weight">
});

用这种方式,我仍然可以使用 DECIMAL SQL 类型(这正是我想要的),并且 TypeScript 类型在我的整个代码库中都能正常工作(weightnumber 类型)。
我认为这种类型断言是安全的,因为当我检查 typeof weight 时,它返回 number,而且(我相信)JavaScript 数字支持我指定的精度。 英文:

What I've done to workaround this is adding type assertion like this:

export const db = mysqlTable(&quot;someDb&quot;, {
  weight: decimal(&quot;weight&quot;, {
    precision: 6, scale: 2
  }) as unknown as MySqlDoubleBuilderInitial&lt;&quot;weight&quot;&gt;
});

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 &quot;number&quot; and (I believe) that javascript number supports my specified precision


赞(1)
未经允许不得转载:工具盒子 » Drizzle ORM – MySQL中的decimal是一个字符串吗?