Справочник декораторов
Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →
Декораторы сущностей
@Entity
Помечает ваш класс как сущность. Сущность — это класс, который преобразуется в таблицу базы данных. Имя таблицы можно указать непосредственно в сущности:
@Entity("users")
export class User {}
Этот код создаст таблицу базы данных с именем "users".
Также можно указать дополнительные параметры сущности:
-
name- имя таблицы. Если не указано, генерируется из имени класса сущности. -
database- имя базы данных на выбранном сервере БД. -
schema- имя схемы. -
comment- комментарий к таблице в базе данных. Поддерживается не всеми типами баз данных. В настоящее время поддерживается в MySQL, MariaDB, PostgreSQL, SAP HANA. -
engine- движок базы данных, устанавливаемый при создании таблицы (работает только в некоторых БД). -
synchronize- сущности сfalseпропускаются при обновлении схемы. -
orderBy- задаёт порядок сортировки по умолчанию для операцийfindиQueryBuilder.
Пример:
@Entity({
name: "users",
engine: "MyISAM",
database: "example_dev",
schema: "schema_with_best_tables",
comment: "This is users table",
synchronize: false,
orderBy: {
name: "ASC",
id: "DESC",
},
})
export class User {}
Подробнее о сущностях.
@ViewEntity
Сущность-представление — это класс, отображаемый на представление базы данных.
@ViewEntity() принимает следующие параметры:
-
name- имя представления. Если не указано, генерируется из имени класса сущности. -
database- имя базы данных на выбранном сервере БД. -
schema- имя схемы. -
expression- определение представл ения. Обязательный параметр.
expression может быть строкой с правильно экранированными столбцами и таблицами (для примера — Postgres):
@ViewEntity({
expression: `
SELECT "post"."id" "id", "post"."name" AS "name", "category"."name" AS "categoryName"
FROM "post" "post"
LEFT JOIN "category" "category" ON "post"."categoryId" = "category"."id"
`,
})
export class PostCategory {}
или экземпляром QueryBuilder
@ViewEntity({
expression: (dataSource: DataSource) =>
dataSource
.createQueryBuilder()
.select("post.id", "id")
.addSelect("post.name", "name")
.addSelect("category.name", "categoryName")
.from(Post, "post")
.leftJoin(Category, "category", "category.id = post.categoryId"),
})
export class PostCategory {}
Примечание: привязка параметров не поддерживается из-за ограничений драйверов. Используйте литеральные параметры.
@ViewEntity({
expression: (dataSource: DataSource) =>
dataSource
.createQueryBuilder()
.select("post.id", "id")
.addSelect("post.name", "name")
.addSelect("category.name", "categoryName")
.from(Post, "post")
.leftJoin(Category, "category", "category.id = post.categoryId")
.where("category.name = :name", { name: "Cars" }) // <-- this is wrong
.where("category.name = 'Cars'"), // <-- and this is right
})
export class PostCategory {}
Подробнее о сущностях-представлениях.
Декораторы столбцов
@Column
Помечает свойство сущности как столбец таблицы. Пример:
@Entity("users")
export class User {
@Column({ primary: true })
id: number
@Column({ type: "varchar", length: 200, unique: true })
firstName: string
@Column({ nullable: true })
lastName: string
@Column({ default: false })
isActive: boolean
}
@Column поддерживает несколько параметров:
-
type: ColumnType- тип столбца. Один из поддерживаемых типов. -
name: string- имя столбца в таблице базы данных. По умолчанию генерируется из имени свойства. Можно переопределить. -
length: string|number- длина типа столбца. Например, для создания типаvarchar(150)укажите тип и длину. -
width: number- ширина отображения для целочисленных типов. Только для MySQL. Устарело в новых версиях MySQL, будет удалено из TypeORM. -
onUpdate: string— ТриггерON UPDATE. Используется только в MySQL. -
nullable: boolean- определяет, может ли столбец бытьNULLили всегдаNOT NULL. По умолчаниюnullable: false. -
update: boolean- разрешает ли обновление значения при операции "save". Если false, значение можно установить только при вставке. По умолчаниюtrue. -
insert: boolean- Указывает, устанавливается ли значение столбца при первой вставке объекта. По умолчаниюtrue. -
select: boolean- Определяет, скрывать ли этот столбец по умолчанию при запросах. Приfalseданные столбца не будут возвращаться стандартным запросом. По умолчаниюselect: true. -
default: string- Задаёт значениеDEFAULTна уровне базы данных. -
primary: boolean- помечает столбец как первичный ключ. Эквивалентно@PrimaryColumn. -
unique: boolean- помечает столбец как уникальный (создаёт ограничение UNIQUE). По умолчанию false. -
comment: string- Комментарий к столбцу в БД. Поддерживается не всеми типами баз данных. -
precision: number- Точность для десятичных столбцов (только для exact numeric), определяющая максимальное количество хранимых цифр. Применяется в некоторых типах столбцов. -
scale: number- масштаб для десятичных столбцов (только для exact numeric), определяющий количество цифр после запятой (не может превышать precision). Применяется в некоторых типах столбцов. -
zerofill: boolean- добавляет атрибутZEROFILLдля числовых столбцов. Только для MySQL. Приtrueавтоматически добавляетсяUNSIGNED. Устарело в новых версиях MySQL, будет удалено из TypeORM. Используйте строковые столбцы и функциюLPAD. -
unsigned: boolean- Добавляет атрибутUNSIGNEDк числовому столбцу. Только для MySQL. -
charset: string- Задаёт кодировку столбца. Поддерживается не всеми типами БД. -
collation: string- Задаёт правила сортировки для столбца. -
enum: string[]|AnyEnum- для типаenumзадаёт допустимые значения. Можно указать массив строк или enum-класс. -
enumName: string- имя генерируемого enum-типа. Если не указано, TypeORM сгенерирует имя из сущности и столбца. Обязательно при использовании одного enum в разных таблицах. -
primaryKeyConstraintName: string- имя ограничения первичного ключа. По умолчанию генерируется из имён таблицы и столбцов. -
asExpression: string- выражение для генерируемого столбца. Только для MySQL и Postgres. -
generatedType: "VIRTUAL"|"STORED"- тип генерируемого столбца. Только для MySQL и Postgres (только "STORED"). -
hstoreType: "object"|"string"- Тип возвращаемого значения дляHSTORE. Возвращает значение как строку или объект. Только для Postgres. -
array: boolean- для типов столбцов Postgres и CockroachDB, которые могут быть массивами (например, int[]). -
transformer: ValueTransformer|ValueTransformer[]- Задаёт трансформер значений (или массив трансформеров), преобразующий данные при чтении/записи в БД. Для массива трансформеры применяются в прямом порядк е (от значения сущности к БД) и обратном (от БД к сущности). -
spatialFeatureType: string- Опциональный тип пространственного объекта (Point,Polygon,LineString,Geometry) для ограничения пространственного столбца. По умолчанию ведёт себя какGeometry. Поддерживается только в PostgreSQL и CockroachDB. -
srid: number- Опциональный идентификатор пространственной привязки для пространственного столбца. По умолчанию0. Координаты WGS84 (широта/долгота) соответствуют EPSG 4326. Поддерживается только в PostgreSQL и CockroachDB.
Подробнее о колонках сущностей.
@PrimaryColumn
Помечает свойство сущности как первичный столбец таблицы.
Аналогичен декоратору @Column, но устанавливает опцию primary в значение true.
Пример:
@Entity()
export class User {
@PrimaryColumn()
id: number
}
@PrimaryColumn() поддерживает кастомное имя ограничения первичного ключа:
@Entity()
export class User {
@PrimaryColumn({ primaryKeyConstraintName: "pk_user_id" })
id: number
}
Примечание: при использовании
primaryKeyConstraintNameс несколькими первичными ключами имя ограничения должно быть одинаковым для всех первичных столбцов.
Подробнее о колонках сущностей.
@PrimaryGeneratedColumn
Помечает свойство сущности как автоматически генерируемый первичный столбец. Создаваемый столбец является первичным, а его значение генерируется автоматически. Пример:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
}
@PrimaryGeneratedColumn() поддерживает кастомное имя ограничения первичного ключа:
@Entity()
export class User {
@PrimaryGeneratedColumn({ primaryKeyConstraintName: "pk_user_id" })
id: number
}
Доступны четыре стратегии генерации:
-
increment- использует AUTO_INCREMENT/SERIAL/SEQUENCE (зависит от БД) для генерации инкрементных чисел. -
identity- только для PostgreSQL 10+. Версии Postgres выше 10 поддерживают SQL-совместимый столбец IDENTITY. Когда стратегия генерации помечена какidentity, столбец будет создан черезGENERATED [ALWAYS|BY DEFAULT] AS IDENTITY. -
uuid- генерирует уникальные строкиuuid. -
rowid- только для CockroachDB. Генерирует 64-битное целое черезunique_rowid()на основе временной метки и ID узла приINSERT/UPSERT.Примечание: свойства со стратегией
rowidдолжны иметь типstring.
Стратегия по умолчанию - increment. Для изменения передайте нужную стратегию первым аргументом декоратора:
@Entity()
export class User {
@PrimaryGeneratedColumn("uuid")
id: string
}
Подробнее о колонках сущностей.
@ObjectIdColumn
Помечает свойство сущности как ObjectId.
Этот декоратор используется только в MongoDB.
Каждая сущность в MongoDB должна иметь столбец ObjectId.
Пример:
@Entity()
export class User {
@ObjectIdColumn()
id: ObjectId
}
Подробнее о MongoDB.
@CreateDateColumn
Специальный столбец, автоматически устанавливающийся в время создания сущности. Не требует ручного заполнения - значение устанавливается автоматически. Пример:
@Entity()
export class User {
@CreateDateColumn()
createdDate: Date
}
@UpdateDateColumn
Специальный столбец, автоматически обновляющийся до времени изменения сущности при каждом вызове save из менеджера сущностей или репозитория. Не требует ручного заполнения - значение обновляется автоматически.
Этот столбец также автоматически обновляется во время операций upsert при обновлении из-за конфликта.
@Entity()
export class User {
@UpdateDateColumn()
updatedDate: Date
}
@DeleteDateColumn
Специальный столбец, который автоматически устанавливается во время удаления сущности при каждом вызове soft-delete в менеджере или репозитории. Вам не нужно задавать значение для этого столбца — он устанавливается автоматически.
Функция мягкого удаления в TypeORM использует глобальные скоупы для выборки только "неудалённых" сущностей из базы данных.
Если установлен @DeleteDateColumn, стандартным скоупом будут "неудалённые" записи.
@Entity()
export class User {
@DeleteDateColumn()
deletedDate: Date
}
@VersionColumn
Специальный столбец, который автоматически устанавливается как версия сущности (инкрементное число) при каждом вызове save в менеджере или репозитории. Вам не нужно задав ать значение для этого столбца — он устанавливается автоматически.
Этот столбец также автоматически обновляется во время операций upsert при обновлении из-за конфликта.
@Entity()
export class User {
@VersionColumn()
version: number
}
@Generated
Помечает столбец как генерируемое значение. Например:
@Entity()
export class User {
@Column()
@Generated("uuid")
uuid: string
}
Значение генерируется только один раз перед вставкой сущности в базу данных.
@VirtualColumn
Специальный столбец, который никогда не сохраняется в базе данных и действует как свойство только для чтения. При каждом вызове find или findOne в менеджере сущностей значение пересчитывается на основе функции запроса, указанной в декораторе VirtualColumn. Аргумент alias, передаваемый в запрос, ссылается на псевдоним сущности в сгенерированном запросе.
@Entity({ name: "companies", alias: "COMP" })
export class Company extends BaseEntity {
@PrimaryColumn("varchar", { length: 50 })
name: string
@VirtualColumn({
query: (alias) =>
`SELECT COUNT("name") FROM "employees" WHERE "companyName" = ${alias}.name`,
})
totalEmployeesCount: number
@OneToMany((type) => Employee, (employee) => employee.company)
employees: Employee[]
}
@Entity({ name: "employees" })
export class Employee extends BaseEntity {
@PrimaryColumn("varchar", { length: 50 })
name: string
@ManyToOne((type) => Company, (company) => company.employees)
company: Company
}
Декораторы отношений
@OneToOne
Отношение "один-к-одному" — когда A содержит только один экземпляр B, а B содержит только один экземпляр A. Например, сущности User и Profile. Пользователь может иметь только один профиль, а один профиль принадлежит только одному пользователю. Пример:
import { Entity, OneToOne, JoinColumn } from "typeorm"
import { Profile } from "./Profile"
@Entity()
export class User {
@OneToOne((type) => Profile, (profile) => profile.user)
@JoinColumn()
profile: Profile
}
Подробнее об отношениях один-к-одному.
@ManyToOne
Отношение "многие-к-одному" / "один-ко-многим" — когда A содержит несколько экземпляров B, но B содержит только один экземпляр A. Например, сущности User и Photo. Пользователь может иметь несколько фотографий, но каждая фотография принадлежит только одному пользователю. Пример:
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from "typeorm"
import { User } from "./User"
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number
@Column()
url: string
@ManyToOne((type) => User, (user) => user.photos)
user: User
}
Подробнее об отношениях многие-к-одному / один-ко-многим.
@OneToMany
Отношение "многие-к-одному" / "один-ко-многим" — когда A содержит несколько экземпляров B, но B содержит только один экземпляр A. Например, сущности User и Photo. Пользователь может иметь несколько фотографий, но каждая фотография принадлежит только одному пользователю. Пример:
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from "typeorm"
import { Photo } from "./Photo"
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToMany((type) => Photo, (photo) => photo.user)
photos: Photo[]
}
Подробнее об отношениях многие-к-одному / один-ко-многим.
@ManyToMany
Отношение "многи е-ко-многим" — когда A содержит несколько экземпляров B, а B содержит несколько экземпляров A. Например, сущности Question и Category. Вопрос может иметь несколько категорий, а каждая категория может принадлежать нескольким вопросам. Пример:
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToMany,
JoinTable,
} from "typeorm"
import { Category } from "./Category"
@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number
@Column()
title: string
@Column()
text: string
@ManyToMany((type) => Category)
@JoinTable()
categories: Category[]
}
Подробнее об отношениях многие-ко-многим.
@JoinColumn
Определяет, на какой стороне отношения находится столбец соединения с внешним ключом, и позволяет кастомизировать имя столбца соединения, имя ссылающегося столбца и имя внешнего ключа. Пример:
@Entity()
export class Post {
@ManyToOne((type) => Category)
@JoinColumn({
name: "cat_id",
referencedColumnName: "name",
foreignKeyConstraintName: "fk_cat_id",
})
category: Category
}
@JoinTable
Используется для отношений many-to-many и описывает соединительные столбцы в "связующей" таблице.
Связующая таблица — это специальная отдельная таблица, автоматически создаваемая TypeORM, содержащая с толбцы, ссылающиеся на связанные сущности.
Вы можете изменить имя генерируемой связующей таблицы, имена столбцов внутри неё, их целевые
столбцы с помощью атрибутов joinColumn и inverseJoinColumn, а также имена создаваемых внешних ключей.
Также можно установить параметр synchronize в false, чтобы пропустить обновление схемы (аналогично @Entity).
Пример:
@Entity()
export class Post {
@ManyToMany((type) => Category)
@JoinTable({
name: "question_categories",
joinColumn: {
name: "question",
referencedColumnName: "id",
foreignKeyConstraintName: "fk_question_categories_questionId",
},
inverseJoinColumn: {
name: "category",
referencedColumnName: "id",
foreignKeyConstraintName: "fk_question_categories_categoryId",
},
synchronize: false,
})
categories: Category[]
}
Если целевая таблица имеет составной первичный ключ,
в декоратор @JoinTable необходимо передать массив свойств.
@RelationId
Загружает идентификатор (или идентификаторы) определённых связей в свойства.
Например, если в вашей сущности Post есть связь many-to-one category,
вы можете получить новый идентификатор категории, пометив новое свойство @RelationId.
Пример:
@Entity()
export class Post {
@ManyToOne((type) => Category)
category: Category
@RelationId((post: Post) => post.category) // you need to specify target relation
categoryId: number
}
Эта функциональность работает для всех типов отношений, включая many-to-many:
@Entity()
export class Post {
@ManyToMany((type) => Category)
categories: Category[]
@RelationId((post: Post) => post.categories)
categoryIds: number[]
}
Идентификатор связи используется только для представления. Базовая связь не добавляется/удаляется/изменяется при смене значения.
Декораторы подписчиков и слушателей
@AfterLoad
Вы можете определить метод с любым именем в сущности и пометить его @AfterLoad.
TypeORM будет вызывать его каждый раз при загрузке сущности
через QueryBuilder или методы find репозитория/менеджера.
Пример:
@Entity()
export class Post {
@AfterLoad()
updateCounters() {
if (this.likesCount === undefined) this.likesCount = 0
}
}
Подробнее о слушателях.
@BeforeInsert
Вы можете определить метод с любым именем в сущности и пометить его @BeforeInsert.
TypeORM будет вызывать его перед вставкой сущности через save репозитория/менеджера.
Пример:
@Entity()
export class Post {
@BeforeInsert()
updateDates() {
this.createdDate = new Date()
}
}
Подробнее о слушателях.
@AfterInsert
Вы можете определить метод с любым именем в сущности и пометить его @AfterInsert.
TypeORM будет вызывать его посл е вставки сущности через save репозитория/менеджера.
Пример:
@Entity()
export class Post {
@AfterInsert()
resetCounters() {
this.counters = 0
}
}
Подробнее о слушателях.
@BeforeUpdate
Вы можете определить метод с любым именем в сущности и пометить его @BeforeUpdate.
TypeORM будет вызывать его перед обновлением существующей сущности через save репозитория/менеджера.
Пример:
@Entity()
export class Post {
@BeforeUpdate()
updateDates() {
this.updatedDate = new Date()
}
}
Подробнее о слушателях.
@AfterUpdate
Вы можете определить метод с любым именем в сущности и пометить его @AfterUpdate.
TypeORM будет вызывать его после обновления существующей сущности через save репозитория/менеджера.
Пример:
@Entity()
export class Post {
@AfterUpdate()
updateCounters() {
this.counter = 0
}
}
Подробнее о слушателях.
@BeforeRemove
Вы можете определить в сущности метод с любым именем и пометить его @BeforeRemove,
и TypeORM вызовет его перед удалением сущности с помощью remove из репозитория/менеджера.
Пример:
@Entity()
export class Post {
@BeforeRemove()
updateStatus() {
this.status = "removed"
}
}
Подробнее о слушателях.
@AfterRemove
Вы можете определить метод с любым именем в сущности и пометить его @AfterRemove.
TypeORM будет вызывать его после удаления сущности через remove репозитория/менеджера.
Пример:
@Entity()
export class Post {
@AfterRemove()
updateStatus() {
this.status = "removed"
}
}
Подробнее о слушателях.
@BeforeSoftRemove
Вы можете определить в сущност и метод с любым именем и пометить его @BeforeSoftRemove,
и TypeORM вызовет его перед мягким удалением сущности с помощью softRemove из репозитория/менеджера.
Пример:
@Entity()
export class Post {
@BeforeSoftRemove()
updateStatus() {
this.status = "soft-removed"
}
}
Подробнее о слушателях.
@AfterSoftRemove
Вы можете определить метод с любым именем в сущности и пометить его @AfterSoftRemove.
TypeORM будет вызывать его после мягкого удаления сущности через softRemove репозитория/менеджера.
Пример:
@Entity()
export class Post {
@AfterSoftRemove()
updateStatus() {
this.status = "soft-removed"
}
}
Подробнее о слушателях.
@BeforeRecover
Вы можете определить в сущности метод с любым именем и пометить его @BeforeRecover,
и TypeORM вызовет его перед восстановлением сущности с помощью recover из репозитория/менеджера.
Пример:
@Entity()
export class Post {
@BeforeRecover()
updateStatus() {
this.status = "recovered"
}
}
Подробнее о слушателях.
@AfterRecover
Вы можете определить метод с любым именем в сущности и пометить его @AfterRecover.
TypeORM будет вызывать его после восстановления сущности через recover репозитория/менеджера.
Пример:
@Entity()
export class Post {
@AfterRecover()
updateStatus() {
this.status = "recovered"
}
}
Подробнее о слушателях.
@EventSubscriber
Помечает класс как подписчика событий, который может прослушивать события конкретных сущностей или любых сущностей.
События генерируются при использовании QueryBuilder и методов репозитория/менеджера.
Пример:
@EventSubscriber()
export class PostSubscriber implements EntitySubscriberInterface<Post> {
/**
* Indicates that this subscriber only listen to Post events.
*/
listenTo() {
return Post
}
/**
* Called before post insertion.
*/
beforeInsert(event: InsertEvent<Post>) {
console.log(`BEFORE POST INSERTED: `, event.entity)
}
}
Вы можете реализовать любой метод из EntitySubscriberInterface.
Для прослушивания любых сущностей просто опустите метод listenTo и используйте any:
@EventSubscriber()
export class PostSubscriber implements EntitySubscriberInterface {
/**
* Called before entity insertion.
*/
beforeInsert(event: InsertEvent<any>) {
console.log(`BEFORE ENTITY INSERTED: `, event.entity)
}
}
Подробнее о подписчиках.
Прочие декораторы
@Index
Этот декоратор позволяет создавать индекс в базе данных для одного или нескольких столбцов. Он также позволяет пометить столбец или столбцы как уникальные. Декоратор может применяться как к отдельным столбцам, так и к самой сущности. Используйте его для столбца, когда требуется индекс на одном столбце, и для сущности — когда нужен один индекс на нескольких столбцах. Примеры:
@Entity()
export class User {
@Index()
@Column()
firstName: string
@Index({ unique: true })
@Column()
lastName: string
}
@Entity()
@Index(["firstName", "lastName"])
@Index(["lastName", "middleName"])
@Index(["firstName", "lastName", "middleName"], { unique: true })
export class User {
@Column()
firstName: string
@Column()
lastName: string
@Column()
middleName: string
}
Узнайте больше об индексах.
@Unique
Этот декоратор позволяет создавать ограничение уникальности (unique constraint) в базе данных для одного или нескольких столбцов. Декоратор применяется только к сущности. В качестве аргументов необходимо указывать имена полей сущности (а не имена столбцов базы данных).
Примеры:
@Entity()
@Unique(["firstName"])
@Unique(["lastName", "middleName"])
@Unique("UQ_NAMES", ["firstName", "lastName", "middleName"])
export class User {
@Column({ name: "first_name" })
firstName: string
@Column({ name: "last_name" })
lastName: string
@Column({ name: "middle_name" })
middleName: string
}
Примечание: MySQL хранит ограничения уникальности в виде уникальных индексов.
@Check
Этот декоратор позволяет создавать check-ограничение для одного или нескольких столбцов. Декоратор применяется только к сущности.
Примеры:
@Entity()
@Check(`"firstName" <> 'John' AND "lastName" <> 'Doe'`)
@Check(`"age" > 18`)
export class User {
@Column()
firstName: string
@Column()
lastName: string
@Column()
age: number
}
Примечание: MySQL не поддерживает check-ограничения.
@Exclusion
Этот декоратор позволяет создавать ограничение-исключение (exclusion constraint) для одного или нескольких столбцов. Декоратор применяется только к сущности.
Примеры:
@Entity()
@Exclusion(`USING gist ("room" WITH =, tsrange("from", "to") WITH &&)`)
export class RoomBooking {
@Column()
room: string
@Column()
from: Date
@Column()
to: Date
}
Примечание: Ограничения-исключения поддерживаются только в PostgreSQL.
@ForeignKey
Этот декоратор позволяет создавать внешний ключ в базе данных для одного или нескольких столбцов. Декоратор может применяться как к отдельным столбцам, так и к сущности. Используйте его для столбца, когда требуется внешний ключ на одном столбце, и для сущности — когда нужен один внешний ключ на нескольких столбцах.
Примечание: Не используйте этот декоратор вместе с отношениями. Внешние ключи создаются автоматически для отношений, которые вы определяете через декораторы отношений (
@ManyToOne,@OneToOneи т.д.). Декоратор@ForeignKeyследует использовать только для создания внешних ключей в базе данных, когда вы не хотите определять эквивалентное отношение между сущностями.
Примеры:
@Entity("orders")
@ForeignKey(() => City, ["cityId", "countryCode"], ["id", "countryCode"])
export class Order {
@PrimaryColumn()
id: number
@Column("uuid", { name: "user_uuid" })
@ForeignKey<User>("User", "uuid", { name: "FK_user_uuid" })
userUuid: string
@Column({ length: 2 })
@ForeignKey(() => Country, "code")
countryCode: string
@Column()
@ForeignKey("cities")
cityId: number
@Column()
dispatchCountryCode: string
@ManyToOne(() => Country)
dispatchCountry: Country
@Column()
dispatchCityId: number
@ManyToOne(() => City)
dispatchCity: City
}
@Entity("cities")
@Unique(["id", "countryCode"])
export class City {
@PrimaryColumn()
id: number
@Column({ length: 2 })
@ForeignKey("countries", { onDelete: "CASCADE", onUpdate: "CASCADE" })
countryCode: string
@Column()
name: string
}
@Entity("countries")
export class Country {
@PrimaryColumn({ length: 2 })
code: string
@Column()
name: string
}
@Entity("users")
export class User {
@PrimaryColumn({ name: "ref" })
id: number
@Column("uuid", { unique: true })
uuid: string
}