如何解决Drizzle ORM多对多关联表的关联推断信息不足错误
PostgreSQL + Drizzle ORM 多对多关联报错解决
问题描述
用PostgreSQL结合Drizzle ORM实现TemplateDefinitions与ColorSets的双向多对多关联,已为关联双方添加关联名称,但仍触发错误:
Error: There is not enough information to infer relation "TemplateDefinitions.colorSets"
尝试给关联表的relation()定义添加关联名时,又提示存在同名关联。所有多对多关联均出现类似问题,仅一对多关联的with查询可正常运行。
现有Schema代码
export const TemplateDefinitions = pgTable('template_definitions', { id: uuid('id').primaryKey().defaultRandom(), name: varchar('name', { length: 256 }).notNull(), }) // 多对多关联表 export const templateDefinitionToColorSets = pgTable( 'template_definition_to_color_sets', { templateDefinitionId: uuid('template_definition_id') .references((): AnyPgColumn => TemplateDefinitions.id) .notNull(), colorSetId: uuid('color_set_id') .references(() => ColorSets.id) .notNull(), }, (table) => ({ pk: primaryKey({ columns: [table.templateDefinitionId, table.colorSetId] }), }) ) export const templateDefinitionToColorSetsRelations = relations( templateDefinitionToColorSets, ({ one }) => ({ colorSet: one(ColorSets, { fields: [templateDefinitionToColorSets.colorSetId], references: [ColorSets.id], }), templateDefinition: one(TemplateDefinitions, { fields: [templateDefinitionToColorSets.templateDefinitionId], references: [TemplateDefinitions.id], }), }) ) export const templateDefinitionRelations = relations( TemplateDefinitions, ({ one, many }) => ({ templates: many(Templates), tokenDefinitions: many(templateToTokenDefinitions), categories: many(templateDefinitionToCategories, { relationName: 'templateDefinitionToCategories', }), colorSets: many(templateDefinitionToColorSets, { relationName: 'templateDefinitionToColorSets', }), }) ) // ColorSets表定义 export const ColorSets = pgTable('color_sets', { id: uuid('id').primaryKey().defaultRandom(), name: varchar('name', { length: 256 }).notNull(), }) export const colorSetRelations = relations(ColorSets, ({ one, many }) => ({ colors: many(Color), templateDefinitions: many(templateDefinitionToColorSets, { relationName: 'templateDefinitionToColorSets', }), }))
触发错误的查询代码
const templateDefinition = await db.query.TemplateDefinitions.findFirst({ where: eq(TemplateDefinitions.id, id), with: { colorSets: { with: { colorSet: true, }, }, }, })
解决方案
问题根源在于多对多关联的relationName未形成双向匹配,Drizzle无法正确推断关联关系。需为中间表的两个one关联分别指定唯一的relationName,并与主表的many关联对应:
1. 修改中间表的relations定义
为两个one关联添加不同的relationName:
export const templateDefinitionToColorSetsRelations = relations( templateDefinitionToColorSets, ({ one }) => ({ colorSet: one(ColorSets, { fields: [templateDefinitionToColorSets.colorSetId], references: [ColorSets.id], // 指定关联名,与ColorSets的many关联对应 relationName: 'color_set_to_template' }), templateDefinition: one(TemplateDefinitions, { fields: [templateDefinitionToColorSets.templateDefinitionId], references: [TemplateDefinitions.id], // 指定关联名,与TemplateDefinitions的many关联对应 relationName: 'template_to_color_set' }), }) )
2. 修改主表的relations定义
将主表的many关联的relationName与中间表对应:
// 修改TemplateDefinitions的relations export const templateDefinitionRelations = relations( TemplateDefinitions, ({ one, many }) => ({ templates: many(Templates), tokenDefinitions: many(templateToTokenDefinitions), categories: many(templateDefinitionToCategories, { relationName: 'templateDefinitionToCategories', }), colorSets: many(templateDefinitionToColorSets, { // 匹配中间表中templateDefinition的relationName relationName: 'template_to_color_set', }), }) ) // 修改ColorSets的relations export const colorSetRelations = relations(ColorSets, ({ one, many }) => ({ colors: many(Color), templateDefinitions: many(templateDefinitionToColorSets, { // 匹配中间表中colorSet的relationName relationName: 'color_set_to_template', }), }))
原理说明
Drizzle ORM需要通过唯一的relationName建立主表与中间表的关联映射。多对多场景下,中间表的两个one关联必须分别指定不同的relationName,避免命名冲突,同时确保主表的many关联能精准匹配到中间表对应的关联定义,从而完成关系推断。
内容的提问来源于stack exchange,提问作者Connorelsea
相关产品推荐
相关产品推荐

