drizzle-orm@0.32.0 和 drizzle-kit@0.23.0 的发布说明
升级这两个包并不是强制的,但如果您希望在查询和迁移中使用新功能,则需要同时升级这两个包。
新功能
🎉 MySQL $returningId() 函数
MySQL 本身在使用 INSERT 后并不支持 RETURNING。对于 自增(或 序列)类型的 主键,只有一种方法可以做到,即访问 insertId 和 affectedRows 字段。我们为您准备了一种自动处理此类情况的方法,使用 Drizzle 并自动接收所有插入的 ID 作为单独对象。
import { boolean, int, text, mysqlTable } from 'drizzle-orm/mysql-core';
const usersTable = mysqlTable('users', {
id: int('id').primaryKey(),
name: text('name').notNull(),
verified: boolean('verified').notNull().default(false),
});
const result = await db.insert(usersTable).values([{ name: 'John' }, { name: 'John1' }]).$returningId();
// ^? { id: number }[]使用 Drizzle,您还可以通过 $default 函数指定 主键,该函数将在运行时生成自定义主键。我们也会在 $returningId() 调用中返回这些生成的键。
import { varchar, text, mysqlTable } from 'drizzle-orm/mysql-core';
import { createId } from '@paralleldrive/cuid2';
const usersTableDefFn = mysqlTable('users_default_fn', {
customId: varchar('id', { length: 256 }).primaryKey().$defaultFn(createId),
name: text('name').notNull(),
});
const result = await db.insert(usersTableDefFn).values([{ name: 'John' }, { name: 'John1' }]).$returningId();
// ^? { customId: string }[]如果没有主键 -> 此类查询的类型将是
{}[]。
🎉 PostgreSQL 序列
现在您可以在 Postgres 中指定任何需要的模式中的序列,并定义所有可用属性。
示例
import { pgSchema, pgSequence } from "drizzle-orm/pg-core";
// 未指定参数
export const customSequence = pgSequence("name");
// 带参数的序列
export const customSequence = pgSequence("name", {
startWith: 100,
maxValue: 10000,
minValue: 100,
cycle: true,
cache: 10,
increment: 2
});
// 自定义模式中的序列
export const customSchema = pgSchema('custom_schema');
export const customSequence = customSchema.sequence("name");🎉 PostgreSQL 标识列
来源:如前文所述,Postgres 中的 serial 类型已过时,应该被弃用。理想情况下,您不应该使用它。标识列 是在您的模式中指定序列的推荐方式,这也是我们引入 标识列 特性的原因。
示例
import { pgTable, integer, text } from 'drizzle-orm/pg-core'
export const ingredients = pgTable("ingredients", {
id: integer("id").primaryKey().generatedAlwaysAsIdentity({ startWith: 1000 }),
name: text("name").notNull(),
description: text("description"),
});您可以在 .generatedAlwaysAsIdentity() 函数中指定序列可用的所有属性。此外,您可以为这些序列指定自定义名称。
PostgreSQL 文档 参考。
🎉 PostgreSQL 生成列
现在您可以在任何支持 PostgreSQL 的列上指定生成列,以便使用生成列。
示例 生成列用于 tsvector
注意:在最新发布之前,我们将添加
tsVector列类型。
import { SQL, sql } from "drizzle-orm";
import { customType, index, integer, pgTable, text } from "drizzle-orm/pg-core";
const tsVector = customType<{ data: string }>({
dataType() {
return "tsvector";
},
});
export const test = pgTable(
"test",
{
id: integer("id").primaryKey().generatedAlwaysAsIdentity(),
content: text("content"),
contentSearch: tsVector("content_search", {
dimensions: 3,
}).generatedAlwaysAs(
(): SQL => sql`to_tsvector('english', ${test.content})`
),
},
(t) => ({
idx: index("idx_content_search").using("gin", t.contentSearch),
})
);如果您不需要引用任何表中的列,您可以仅使用 sql 模板或字符串。
export const users = pgTable("users", {
id: integer("id"),
name: text("name"),
generatedName: text("gen_name").generatedAlwaysAs(sql`hello world!`),
generatedName1: text("gen_name1").generatedAlwaysAs("hello world!"),
}),🎉 MySQL 生成列
您现在可以在任何支持 MySQL 的列上指定生成列。
您可以指定 stored 和 virtual 选项,更多信息请查看 MySQL 文档。
此外,MySQL 对于这些列的使用有一些限制,如 这里所述。
Drizzle Kit 也会对 push 命令有一些限制:
-
您不能通过
push更改生成的约束表达式和类型。Drizzle-kit 将忽略此更改。要使其生效,您需要删除列、push,然后添加一个带有新表达式的列。这是由于数据库端复杂的映射,模式表达式将在数据库端被修改,而在内省时我们将得到不同的字符串。我们无法确定您是更改了该表达式,还是数据库进行了更改并重新格式化。由于这些是生成的列,且push主要用于本地数据库的原型设计,因此删除和创建生成列应该很快。由于这些列是生成的,所有数据将被恢复。 -
generate应该没有限制。
示例
export const users = mysqlTable("users", {
id: int("id"),
id2: int("id2"),
name: text("name"),
generatedName: text("gen_name").generatedAlwaysAs(
(): SQL => sql`${schema2.users.name} || 'hello'`,
{ mode: "stored" }
),
generatedName1: text("gen_name1").generatedAlwaysAs(
(): SQL => sql`${schema2.users.name} || 'hello'`,
{ mode: "virtual" }
),
}),如果您不需要引用任何表中的列,您可以在 .generatedAlwaysAs() 中仅使用 sql 模板或字符串。
🎉 SQLite 生成列
您现在可以在任何支持 SQLite 的列上指定生成列。
您可以指定 stored 和 virtual 选项,更多信息请查看 SQLite 文档。
此外,SQLite 对这些列的使用也有一些限制,如 这里所述。
Drizzle Kit 也会对 push 和 generate 命令有一些限制:
-
您不能在现有表中更改存储类型的生成约束表达式。您需要删除此表并重新创建它。这是由于 SQLite 在此类操作中的限制。我们将在未来的发布中处理此情况(这将涉及创建新表和数据迁移)。
-
您不能为同一列添加存储的生成表达式,原因与上述相同。然而,您可以向现有列添加虚拟表达式。
-
您不能更改现有列的存储生成表达式,原因与上述相同。然而,您可以更改虚拟表达式。
-
您不能将生成约束类型从虚拟更改为存储,原因与上述相同。然而,您可以将存储更改为虚拟。
新的 Drizzle Kit 特性
🎉 对所有新 ORM 功能的迁移支持
PostgreSQL 序列、标识列和所有方言的生成列。
🎉 drizzle-kit push 的新标志 --force
您可以在使用 push 命令时自动接受所有数据丢失语句。它仅在 CLI 参数中可用。如果您愿意在数据库上运行数据丢失语句,请务必使用此选项。
🎉 新的 migrations 标志 prefix
您现在可以自定义迁移文件的前缀,以便使格式适合您的迁移工具:
index是默认类型,将生成0001_name.sql文件名;supabase和timestamp相同,将生成20240627123900_name.sql文件名;unix将生成 unix 秒前缀1719481298_name.sql文件名;none将完全省略前缀;
示例:Supabase 迁移格式
import { defineConfig } from "drizzle-kit";
export default defineConfig({
dialect: "postgresql",
migrations: {
prefix: 'supabase'
}
});