如何使用Drizzle ORM向存在多对多关系的两张表中插入数据
如何使用Drizzle ORM向存在多对多关系的两张表中插入数据
嘿,我来帮你把这段Prisma代码转成Drizzle的写法~ 毕竟Drizzle在处理多对多关联数据插入时,没有Prisma那种connect的便捷语法,得我们手动拆分步骤处理,而且最好用事务包裹操作,确保所有步骤要么都成功要么都失败,避免数据不一致。
首先得确保你的Drizzle Schema已经正确定义了这三张表(主表+中间关联表),我给你个参考示例:
import { pgTable, serial, varchar, integer, boolean, timestamp, primaryKey } from 'drizzle-orm/pg-core'; // 如果用MySQL,替换成mysql-core对应的方法即可 // 产品表 export const productTable = pgTable('productTable', { id: serial('id').primaryKey(), // 这里可以添加你的其他产品字段,比如name、price等 }); // 折扣码表 export const discountCodeTable = pgTable('discountCodeTable', { id: serial('id').primaryKey(), code: varchar('code', { length: 50 }).notNull(), discountAmount: integer('discountAmount').notNull(), discountType: varchar('discountType').notNull(), // 如果是枚举类型,可用Drizzle的enum方法定义 allProducts: boolean('allProducts').notNull(), expiredAt: timestamp('expiredAt'), limit: integer('limit'), }); // 多对多关联中间表 export const productToDiscount = pgTable('productToDiscount', { productId: integer('productId') .notNull() .references(() => productTable.id), discountCodeId: integer('discountCodeId') .notNull() .references(() => discountCodeTable.id), }, (table) => ({ // 设置复合主键,避免同一产品和折扣码重复关联 pk: primaryKey(table.productId, table.discountCodeId), }));
接下来就是核心的插入逻辑,我们需要先创建折扣码记录,再根据传入的productIds插入中间表的关联数据,用事务包裹这两个操作:
import { db } from './your-db-setup'; // 导入你的Drizzle数据库实例 import { discountCodeTable, productToDiscount } from './your-schema-file'; import { DiscountCodeType } from './your-enum-definition'; // 导入你的折扣类型枚举 async function createDiscountCode(data: { code: string; discountAmount: number; discountType: DiscountCodeType; allProducts: boolean; productIds?: number[]; expiredAt?: Date; limit?: number; }) { return await db.transaction(async (tx) => { // 第一步:插入折扣码到主表,用returning()获取刚创建的折扣码数据(包含id) const [newDiscountCode] = await tx.insert(discountCodeTable) .values({ code: data.code, discountAmount: data.discountAmount, discountType: data.discountType, allProducts: data.allProducts, expiredAt: data.expiredAt, limit: data.limit, }) .returning(); // 第二步:如果传入了productIds,批量插入中间表的关联记录 if (data.productIds?.length) { const associationRecords = data.productIds.map(productId => ({ productId, discountCodeId: newDiscountCode.id, })); await tx.insert(productToDiscount) .values(associationRecords); } return newDiscountCode; }); }
这里和Prisma的主要区别在于:
- Drizzle不会自动处理多对多的关联插入,需要手动拆分「创建主记录」和「插入关联记录」两个步骤
- 用
transaction包裹操作,保证两个步骤的原子性——如果其中一步失败,整个操作会回滚,不会留下半截数据 - 通过
returning()方法获取刚插入的折扣码ID,这是关联产品的关键
不管你用的是PostgreSQL还是MySQL,核心逻辑都是一样的,只是Schema定义时的字段类型方法会略有不同~
备注:内容来源于stack exchange,提问作者Pooyan Honari
相关产品推荐
相关产品推荐

