Недавно я столкнулся с проблемой: я хотел создать правило уникальности базы данных, которое будет выдавать ошибку при наличии дублирующейся записи на основе определенных полей в таблице базы данных.
Сложность заключалась в том, что одно из этих полей было связано с другой таблицей, и я не был уверен, как это реализовать.
Чтобы дать немного больше контекста, давайте рассмотрим следующий пример.
Предположим, что у нас есть школьный класс, состоящий из учеников, и в нашем классе мы хотим избежать ситуаций, когда будут два ученика с одинаковым именем (два ученика могут появиться в нашей таблице, но только если они находятся в разных классах).
Class (1) => Student (N)
Код
Обычно, если мы хотим добиться уникальности нашей таблицы, мы можем сделать это в TypeORM (а также в обычном SQL), используя ключевое слово UNIQUE
. В TypeORM мы используем декораторы @Unique(param)
и в качестве параметра передаем имя поля, которое мы хотим сделать уникальным (т.е. @Unique('name')
).
Однако в нашем случае мы должны использовать другое ключевое слово SQL и декоратор TypeORM.
Давайте посмотрим на нашу сущность Student:
import {
Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
} from 'typeorm';
import { SchoolClass } from '../school-class.entity';
@Entity()
export class StudentEntity {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => SchoolClass, (schoolClass) => schoolClass.students)
schoolClass: SchoolClass;
@Column()
name: string;
}
Наша таблица имеет три столбца:
Для решения проблемы с уникальными именами в школьном классе мы будем использовать декоратор @Index
(который затем преобразуется в INDEX
в SQL).
import {
Entity,
Column,
PrimaryGeneratedColumn,
ManyToOne,
Index,
} from 'typeorm';
import { SchoolClass } from '../school-class.entity';
@Entity()
@Index(['name', 'schoolClass'], { unique: true }) // Here
export class StudentEntity {
@PrimaryGeneratedColumn()
id: number;
@ManyToOne(() => SchoolClass, (schoolClass) => schoolClass.students)
schoolClass: SchoolClass;
@Column()
name: string;
}
Мы передаем в виде массива значения, которые хотим использовать (в нашем случае name
и schoolClass
). Мы также передадим объект options со свойством unique
, установленным в true
. Это гарантирует, что вставка новой записи в нашу базу данных с тем же именем в школьном классе приведет к ошибке DUPLICATE_ENTRY
.
Резюме
Отлично сработано! Вы только что узнали, как создать уникальные правила для вставки новых данных в базу данных. Надеюсь, это поможет вам решить аналогичную проблему, с которой я недавно столкнулся 🙂