TypeORM уникальные индексы с несколькими полями

Недавно я столкнулся с проблемой: я хотел создать правило уникальности базы данных, которое будет выдавать ошибку при наличии дублирующейся записи на основе определенных полей в таблице базы данных.

Сложность заключалась в том, что одно из этих полей было связано с другой таблицей, и я не был уверен, как это реализовать.

Чтобы дать немного больше контекста, давайте рассмотрим следующий пример.

Предположим, что у нас есть школьный класс, состоящий из учеников, и в нашем классе мы хотим избежать ситуаций, когда будут два ученика с одинаковым именем (два ученика могут появиться в нашей таблице, но только если они находятся в разных классах).

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.

Резюме

Отлично сработано! Вы только что узнали, как создать уникальные правила для вставки новых данных в базу данных. Надеюсь, это поможет вам решить аналогичную проблему, с которой я недавно столкнулся 🙂

Оцените статью
devanswers.ru
Добавить комментарий