drizzle-orm@0.32.0
和 drizzle-kit@0.23.0
发行说明
升级两个软件包并非强制性要求,但如果你想在查询和迁移中使用新功能,则需要升级两个软件包。
新功能
🎉 MySQL $returningId()
函数
使用 INSERT
后,MySQL 本身不再原生支持 RETURNING
。对于 primary keys
类型,只有一种方法可以访问 autoincrement
(或 serial
)类型的 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
函数的 primary key
,该函数将在运行时生成自定义主键。我们还会在 $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";
// No params specified
export const customSequence = pgSequence("name");
// Sequence with params
export const customSequence = pgSequence("name", {
startWith: 100,
maxValue: 10000,
minValue: 100,
cycle: true,
cache: 10,
increment: 2
});
// Sequence in custom schema
export const customSchema = pgSchema('custom_schema');
export const customSequence = customSchema.sequence("name");
🎉 PostgreSQL 标识列
数据源:如上所述,Postgres 中的 serial
类型已过时,应予以弃用。理想情况下,你不应该使用它。Identity columns
是推荐的在模式中指定序列的方式,这也是我们引入 identity columns
功能的原因。
示例
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 文档 reference。
🎉 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
模板或 string
模板。
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 将忽略此更改。要使其正常工作,你需要先执行drop the column
、push
,然后执行add a column with a new expression
。这样做是因为数据库端的映射很复杂,模式表达式会在数据库端被修改,并且在自省时,我们会得到不同的字符串。我们无法确定你是否更改了此表达式,或者它是否已被数据库更改和格式化。只要这些是生成的列,并且push
主要用于在本地数据库上进行原型设计,那么drop
和create
生成的列应该会很快。由于这些列是generated
,因此所有数据都将被恢复。 -
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" }
),
}),
如果你不需要引用表中的任何列,你可以只使用 sql
模板或 .generatedAlwaysAs()
中的 string
模板。
🎉 SQLite 生成的列
你现在可以在 SQLite 支持的任何列上指定生成的列,以便与生成的列一起使用。
你可以同时指定 stored
和 virtual
选项,更多信息请查看 SQLite 文档。
SQLite 对此类列的使用也有一些限制,详见 此处。
Drizzle Kit 对 push
和 generate
命令也存在限制:
-
你无法使用现有表中的存储类型更改生成的约束表达式。你需要删除此表并重新创建。这是由于 SQLite 对此类操作的限制。我们将在未来的版本中处理这种情况(这将涉及创建带有数据迁移功能的新表)。
-
出于与上述相同的原因,你无法将
stored
生成的表达式添加到现有列。但是,你可以将virtual
表达式添加到现有列。 -
出于与上述相同的原因,你无法更改现有列中
stored
生成的表达式。但是,你可以更改virtual
表达式。 -
出于与上述相同的原因,你无法将生成的约束类型从
virtual
更改为stored
。但是,你可以将stored
更改为virtual
。
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'
}
});