Как установить настраиваемую уникальную строку идентификатора по умолчанию для @PrimaryGeneratedColumn в объекте TypeORM?

У меня есть вариант использования, который требует использования настраиваемого строкового первичного ключа в моих таблицах. (Я не хочу использовать uuid по умолчанию, предоставляемый GraphQL, но вместо этого хочу использовать библиотека шорттид для создания пользовательского уникального идентификатора.)

Я новичок в TypeORM, и я ничего не нахожу в документации о настройке настраиваемого первичного ключа по умолчанию. Можно ли добиться того, что я хочу, в TypeORM PrimaryGeneratedColumn, или мне нужно добиться того, что я хочу, другими способами?

ОБНОВЛЕНИЕ: я узнал, что могу использовать @BeforeInsert слушатель для изменения сущностей перед их сохранением, но TypeORM по-прежнему не позволяет мне переопределить PrimaryGeneratedColumn ('uuid') и использовать строку shortId, потому что строка shortId не является допустимым uuid.

В зависимости от того, какую базу данных вы используете, указание @PrimaryGeneratedColumn('uuid') означает, что тип поля базы данных будет uuid, в который вы не можете вставить недопустимый UUID. Я бы предложил украсить @PrimaryColumn ('символ', {длина: <длина shortId>}) и использовать прослушиватель @BeforeInsert, как вы описываете. Это даст вам первичный ключ символа фиксированной длины для shortId.

Timshel 04.09.2018 06:56

Снова посмотрев на документы shortId, я заметил, что сгенерированный идентификатор может иметь переменную длину; если это так, вы захотите использовать @PrimaryColumn('varchar', { length: <max-shortid-length> }) вместо вышеуказанного ...

Timshel 04.09.2018 08:39

@PrimaryColumn - это именно то, что мне нужно. Я такой новичок, что даже не знал, что PrimaryColumn был декоратором: # мой код выглядел как этот @PrimaryColumn('varchar', { default: shortid.generate(), length: 14 }), спасибо за вашу помощь! Я бы проголосовал за ваши комментарии, но это не позволяет мне: /

m_downey 04.09.2018 09:35

Размещено как ответ, так что вы можете проголосовать за него! Кстати, с опцией столбца default, вы передаете саму функцию (например, default: shortid.generate) или вызываете ее и по умолчанию используете ее возвращаемое значение (default: shortid.generate())? Если я не ошибаюсь, вам понадобится первое - в противном случае TypeORM будет иметь одно значение по умолчанию при каждом запуске вашего приложения и позволит вставлять одну запись, но затем ошибку с дублированием нарушения ключа для последующих записей.

Timshel 04.09.2018 14:51

@Timshel, вы правы, я столкнулся с двойным нарушением ключа. Однако, когда я попробовал рекомендованное вами изменение, я продолжал сталкиваться с ошибкой column "gz68lzqnmn" does not exist (идентификатор меняется каждый раз). Я нашел единственный способ обойти это - оставить default: shortid.generate(), но затем в ловушку BeforeInsert я добавил this.id = shortid.generate(). Очень хакерский и грустный :( но это работает. Если вы хотите глубже изучить это, вы можете вытащить это репо и yarn start для воспроизведения. Никакого давления. Еще раз спасибо! github.com/podverse/podverse-api/tree/primaryDefaultBug

m_downey 07.09.2018 01:36

Я почти уверен, что это проблема с цитированием - возвращаемый идентификатор не цитируется, поэтому интерпретируется как столбец. Обернуть shortid.generate() и указать значение в кавычках должно быть все, что нужно - например, default: () => `'${shortid.generate()}'` (обратите внимание на одинарные кавычки вокруг идентификатора).

Timshel 08.09.2018 04:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
6
10 090
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Декоратор @PrimaryGeneratedColumn('uuid') сопоставляет столбец с типом поля базы данных uuid, если база данных поддерживает его, что означает, что значения столбца должны быть действительными UUID.

Для вашего сценария предлагаю украсить: typescript @PrimaryColumn('varchar', { length: <max shortId length>, default: () => `'${shortid.generate()}'` })

Ответ @ Timshel не работает при использовании SQLite, потому что значения по умолчанию должны быть постоянными. Выдает следующую ошибку:

UnhandledPromiseRejectionWarning: QueryFailedError: SQLITE_ERROR: default value of column [id] is not constant

Вместо этого вы можете использовать @BeforeInsert для достижения желаемого результата, например:

@Field(() => ID)
@PrimaryColumn("varchar", {
  length: 20
})
id: string;

@BeforeInsert()
setId() {
  this.id = shortid.generate();
}

Ответ @ Timshel также не работает для большинства других драйверов. Я протестировал это с помощью MySQL, и когда я создал миграцию из моей сущности, миграция включала: ALTER TABLE user CHANGE id id char(36) NOT NULL DEFAULT 177f7044-0805-4891-870e-8352cffa77bf. Похоже, если вы хотите, чтобы TypeORM выполнял генерацию значений, вам нужно использовать @BeforeInsert

stevendesu 23.04.2020 20:54

возникает другая проблема, поскольку либо невозможно обновить сущности, либо можно предоставить способ создания сущностей с произвольными идентификаторами.

ciekawy 18.09.2020 16:48

Другие вопросы по теме