TypeOrm: создание отношения ManyToOne с использованием типа данных uuid для ключей вместо целого - PullRequest
0 голосов
/ 20 января 2019

У меня есть проект Typescript Nestjs, использующий TypeORM и базу данных PostgreSQL, и у меня возникают проблемы с определением отношений многие-к-одному, потому что TypeORM пытается создать поле идентификатора типа integer, тогда как я использую поля UUID. Есть ли способ сообщить TypeORM использовать тип данных, отличный от целого числа?

Вот пример сущности, которая не работает:

export class AgentKitsEntity implements Model {
  @PrimaryGeneratedColumn()
  @Generated('uuid')
  id: string;
}

@Entity({name: 'users'})
export class User extends AgentKitsEntity implements UserModel {
  @Column()
  username: string;

  @ManyToOne(type => View)
  @JoinColumn({name: 'view_id', referencedColumnName: 'id'})
  view: View;
}

Это приводит к следующей ошибке:

query failed: ALTER TABLE "users" ADD CONSTRAINT "FK_2ed8b186dce83a446f94ac9aae4" FOREIGN KEY ("view_id") REFERENCES "views"("id")
error: { error: foreign key constraint "FK_2ed8b186dce83a446f94ac9aae4" cannot be implemented
    at Connection.parseE (/home/jonathan/projects/agent-kits/api-data/node_modules/pg/lib/connection.js:554:11)
    at Connection.parseMessage (/home/jonathan/projects/agent-kits/api-data/node_modules/pg/lib/connection.js:379:19)
    at Socket.<anonymous> (/home/jonathan/projects/agent-kits/api-data/node_modules/pg/lib/connection.js:119:22)
    at emitOne (events.js:116:13)
    at Socket.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)
    at Socket.Readable.push (_stream_readable.js:208:10)
    at TCP.onread (net.js:601:20)
  name: 'error',
  length: 228,
  severity: 'ERROR',
  code: '42804',
  detail: 'Key columns "view_id" and "id" are of incompatible types: integer and uuid.',
  hint: undefined,
  position: undefined,
  internalPosition: undefined,
  internalQuery: undefined,
  where: undefined,
  schema: undefined,
  table: undefined,
  column: undefined,
  dataType: undefined,
  constraint: undefined,
  file: 'tablecmds.c',
  line: '6503',
  routine: 'ATAddForeignKeyConstraint' }

РЕДАКТИРОВАТЬ: Просто чтобы быть ясно, проблема не в создании поля UUID для первичного ключа, это работает. Проблема заключается в том, что в таблице, на которую я ссылаюсь (в этом примере «views»), используется первичный ключ UUID, поэтому мне нужно использовать UUID и для поля, ссылающегося на него (в данном примере «views»). TypeORM автоматически создает поле «view_id» с целочисленным типом, предположительно потому, что предполагается, что значения первичного ключа будут (должны?) Всегда быть целыми числами (что кажется мне довольно сумасшедшим предположением).

Это должно быть как-то настраиваемо, нет?

1 Ответ

0 голосов
/ 21 января 2019

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

Для меня работает следующее:

export class AgentKitsEntity implements Model {
  @PrimaryGeneratedColumn('uuid')
  @Generated('uuid')
  id: string;
}

@Entity({name: 'users'})
export class User extends AgentKitsEntity implements UserModel {

  @Column()
  username: string;

  @ManyToOne(type => View, { nullable: true })
  @JoinColumn({name: 'view_id'})
  view: View;
}

Ключевое различие, которое кажетсяЯ решил, что я указал 'uuid' в декораторе @PrimaryGeneratedColumn().Это удивительно, поскольку поля фактически были правильно созданы как UUID в базе данных, но кажется, что TypeORM предполагает, что ключевые поля являются целыми числами, если вы явно не указываете тип, даже если он знает достаточно, чтобы выяснить, как создать правильные данныевведите само поле.

РЕДАКТИРОВАТЬ: При ближайшем рассмотрении выясняется, что сущность @Generated ('uuid') является избыточной, и поэтому приведенный выше код для базового класса можно упростить до:

export class AgentKitsEntity implements Model {
  @PrimaryGeneratedColumn('uuid')
  id: string;
}
...