我的数据库遇到过这样的问题:
2023-12-15 12:31:31.913 UTC [95] ERROR: duplicate key value violates unique constraint "users_roles_company_user_id_key"
字符串
一般来说,我所拥有的数据库可以用下面的概念来描述:有不同的公司,公司用户属于公司,公司(他们的用户)可以创建不同的自定义角色,这些角色可以分配给不同的公司用户。
下面是DataGrip生成的这个数据库描述的一部分(我将跳过表的一些不重要的字段):
x1c 0d1x的数据
下面是我编写的模型,用于使用这些外键生成这个数据库:
表格users_roles
:
@Table({ tableName: 'users_roles' })
export class UserRole extends Model<UserRole> {
@PrimaryKey
@Default(DataType.UUIDV4)
@Column(DataType.UUID)
id: string;
@ForeignKey(() => CompanyUser)
@Column({ type: DataType.UUID, allowNull: false, field: 'company_user_id', unique: false })
companyUserId: string;
@ForeignKey(() => Company)
@Column({ type: DataType.UUID, allowNull: false, field: 'company_id', unique: false })
companyId: string;
@ForeignKey(() => Role)
@Column({ type: DataType.UUID, allowNull: false, field: 'role_id', unique: false })
roleId: string;
}
型
表格companies
:
@Table({ tableName: 'companies' })
export class Company extends Model<Company, CompanyCreationAttributes> {
@PrimaryKey
@Default(DataType.UUIDV4)
@Column(DataType.UUID)
id: string;
@BelongsTo(() => User)
user: User;
@HasMany(() => CompanyUser)
companyUsers: Array<CompanyUser>;
@BelongsToMany(() => Role, () => UserRole)
roles: Array<Role>;
}
型
表格roles
:
@Table({ tableName: 'roles' })
export class Role extends Model<Role> {
@PrimaryKey
@Default(DataType.UUIDV4)
@Column(DataType.UUID)
id: string;
@BelongsToMany(() => CompanyUser, () => UserRole)
companyUsers: Array<CompanyUser>;
@BelongsToMany(() => Company, () => UserRole)
companies: Array<Company>;
}
型
表格company_user
:
@Table({ tableName: 'company_users' })
export class CompanyUser extends Model<
CompanyUser,
CompanyUserCreationAttributes
> {
@PrimaryKey
@Default(DataType.UUIDV4)
@Column(DataType.UUID)
id: string;
@ForeignKey(() => User)
@Column({ type: DataType.UUID, allowNull: false, field: 'user_id' })
userId: string;
@ForeignKey(() => Company)
@Column({ type: DataType.UUID, allowNull: false, field: 'company_id' })
companyId: string;
@BelongsTo(() => Company)
company: Company;
@BelongsToMany(() => Role, () => UserRole)
roles: Array<Role>;
}
型
老实说,可能我只是瞎了眼,不能发现错误,因为出于某种原因,在users_roles
中,我可以有2个记录具有相同的company_id
,但不是company_user_id
,或者可能我在某个地方搞砸了数据库外键...
提前感谢大家的帮助!我真的很感激!
编辑日期:
表的索引/约束:
SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),
pg_catalog.pg_get_constraintdef(con.oid, true), contype, condeferrable, condeferred, i.indisreplident, c2.reltablespace
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))
WHERE c.oid = 'users_roles'::regclass::oid AND c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, c2.relname;
型
| 重新命名|医务室|独立的|不成簇的|无效的|pg_获取_索引定义|pg_获取_约束定义|控制型|可供的|延期的|不重复的|关系表空间|
| --|--|--|--|--|--|--|--|--|--|--|--|
| 用户_角色_主键|真正|真正|虚假|真正|CREATE UNIQUE INDEX用户角色主键ON用户角色USING b树(标识)|主键(id)|p|虚假|虚假|虚假| 0 |
| 用户角色公司标识角色标识关键字|虚假|真正|虚假|真正|CREATE UNIQUE INDEX用户角色公司标识角色标识关键字ON用户角色USING b树(公司标识,角色标识)|UNIQUE(公司标识,职责标识)|u|虚假|虚假|虚假| 0 |
| 用户角色公司用户标识关键字|虚假|真正|虚假|真正|CREATE UNIQUE INDEX用户角色公司用户标识关键字ON用户角色USING b树(公司用户标识)|UNIQUE(公司_用户_标识)|u|虚假|虚假|虚假| 0 |
1条答案
按热度按时间b5lpy0ml1#
DataGrip图上的图标表示
users_roles
的所有3个外键列都有索引。其中一个必须是你的意外和不需要的
unique constraint "users_roles_company_user_id_key"
(每个unique constraint builds and uses a unique index自PostgreSQL 16)背后的唯一索引,它是默认@BelongsToMany()
行为的结果:BelongsToMany关联在直通模型的外键上创建唯一键。
您可以通过覆盖
unique
来禁用它:字符串
虽然这里的情况不是这样,但如果直接将外键列定义为unique,也可能会出现此错误:
型
也可以在你的模型中设置一个
@Index
,或者define and sync it separately,甚至完全在其他地方设置一个directly on db--如果你这样设置unique: true
,你也会得到这个错误。索引本身绝对是有帮助的,它只是不应该被设置为唯一的,除非有明显的必要;你需要找到它,并使它成为一个常规的,非唯一的索引。在一个失败的迁移场景中,当你试图改变模型时,出现了一些错误,你没有完全解决这个问题,你也可以有一个来自改变之前的“流浪”唯一索引/约束-在这种情况下,你的CI/CD日志应该告诉你细节。
您可以check your constraints/indexes with DataGrip-在那里,取消勾选 unique 复选框可能就足够了。(在
users_roles
之前添加模式名称)。您可能会看到users_roles_company_user_id_key
被定义为unique
-作为临时解决方案,您可以复制该定义,drop index
并再次运行该定义,在尝试填充表之前,只删除unique
部分。表上的索引/约束:
型
指向此表的外键
型
指向此表的外键
型