传递给 .values() 的所有值都会自动参数化。
例如,这个查询:
await db.insert(users).values({ name: 'Andrew' });将被翻译为:
insert into "users" ("id", "name") values (default, $1) -- params: ['Andrew']传递给 .values() 的所有值都会自动参数化。
例如,这个查询:
await db.insert(users).values({ name: 'Andrew' });将被翻译为:
insert into "users" ("id", "name") values (default, $1) -- params: ['Andrew']Drizzle ORM 为你提供了最接近 SQL 的方式来向数据库表中插入行。
使用 Drizzle 插入数据非常直接,而且很像 SQL。请看:
await db.insert(users).values({ name: 'Andrew' });insert into "users" ("id", "name", "age") values (default, 'Andrew', default)如果你需要某个特定表的插入类型,可以使用 typeof usersTable.$inferInsert 语法。
type NewUser = typeof users.$inferInsert;
const insertUser = async (user: NewUser) => {
return db.insert(users).values(user);
}
const newUser: NewUser = { name: "Alef" };
await insertUser(newUser);你可以在 CockroachDB 中插入一行并将其取回,如下所示:
await db.insert(users).values({ name: "Dan" }).returning();
// 部分返回
await db.insert(users).values({ name: "Partial Dan" }).returning({ insertedId: users.id });await db.insert(users).values([{ name: 'Andrew' }, { name: 'Dan' }]);Drizzle ORM 提供了用于处理 upsert 和冲突的简单接口。
onConflictDoNothing 会在发生冲突时取消插入:
await db.insert(users)
.values({ id: 1, name: 'John' })
.onConflictDoNothing();
// 显式指定冲突目标
await db.insert(users)
.values({ id: 1, name: 'John' })
.onConflictDoNothing({ target: users.id });onConflictDoUpdate 会在发生冲突时更新该行:
await db.insert(users)
.values({ id: 1, name: 'Dan' })
.onConflictDoUpdate({ target: users.id, set: { name: 'John' } });where 子句on conflict do update 可以在两个不同的位置包含 where 子句 -
作为冲突目标的一部分(即用于部分索引),或者作为 update 子句的一部分:
insert into "employees" ("employee_id", "name")
values (123, 'John Doe')
on conflict ("employee_id") where name <> 'John Doe'
do update set "name" = excluded.name;
insert into "employees" ("employee_id", "name")
values (123, 'John Doe')
on conflict ("employee_id") do update set "name" = 'John Doe'
where name <> 'John Doe';要在 Drizzle 中指定这些条件,你可以使用 setWhere 和 targetWhere 子句:
await db.insert(employees)
.values({ employeeId: 123, name: 'John Doe' })
.onConflictDoUpdate({
target: employees.employeeId,
targetWhere: sql`name <> 'John Doe'`,
set: { name: sql`excluded.name` }
});
await db.insert(employees)
.values({ employeeId: 123, name: 'John Doe' })
.onConflictDoUpdate({
target: employees.employeeId,
set: { name: 'John Doe' },
setWhere: sql`name <> 'John Doe'`
});使用复合索引,或用于 onConflictDoUpdate 的复合主键进行 upsert:
await db.insert(users)
.values({ firstName: 'John', lastName: 'Doe' })
.onConflictDoUpdate({
target: [users.firstName, users.lastName],
set: { firstName: 'John1' }
});with insert 子句使用 with 子句可以通过将复杂查询拆分为更小的子查询(称为公用表表达式,CTE)来帮助你简化它们:
const userCount = db.$with('user_count').as(
db.select({ value: sql`count(*)`.as('value') }).from(users)
);
const result = await db.with(userCount)
.insert(users)
.values([
{ username: 'user1', admin: sql`((select * from ${userCount}) = 0)` }
])
.returning({
admin: users.admin
});with "user_count" as (select count(*) as "value" from "users")
insert into "users" ("username", "admin")
values ('user1', ((select * from "user_count") = 0))
returning "admin"正如 CockroachDB 文档所述:
提供要插入的行的查询(SELECT 语句)
Drizzle 支持所有方言的当前语法,并且它们都共享相同的语法。让我们回顾一些常见场景和 API 用法。 在插入语句中使用 select 有几种方式,可以让你选择自己偏好的方法:
const insertedEmployees = await db
.insert(employees)
.select(
db.select({ id: users.id, name: users.name }).from(users).where(eq(users.role, 'employee'))
)
.returning({
id: employees.id,
name: employees.name
});const qb = new QueryBuilder();
await db.insert(employees).select(
qb.select({ id: users.id, name: users.name }).from(users).where(eq(users.role, 'employee'))
);