У меня есть вариант использования, который требует использования настраиваемого строкового первичного ключа в моих таблицах. (Я не хочу использовать uuid по умолчанию, предоставляемый GraphQL, но вместо этого хочу использовать библиотека шорттид для создания пользовательского уникального идентификатора.)
Я новичок в TypeORM, и я ничего не нахожу в документации о настройке настраиваемого первичного ключа по умолчанию. Можно ли добиться того, что я хочу, в TypeORM PrimaryGeneratedColumn, или мне нужно добиться того, что я хочу, другими способами?
ОБНОВЛЕНИЕ: я узнал, что могу использовать @BeforeInsert слушатель для изменения сущностей перед их сохранением, но TypeORM по-прежнему не позволяет мне переопределить PrimaryGeneratedColumn ('uuid') и использовать строку shortId, потому что строка shortId не является допустимым uuid.
Снова посмотрев на документы shortId, я заметил, что сгенерированный идентификатор может иметь переменную длину; если это так, вы захотите использовать @PrimaryColumn('varchar', { length: <max-shortid-length> }) вместо вышеуказанного ...
@PrimaryColumn - это именно то, что мне нужно. Я такой новичок, что даже не знал, что PrimaryColumn был декоратором: # мой код выглядел как этот @PrimaryColumn('varchar', { default: shortid.generate(), length: 14 }), спасибо за вашу помощь! Я бы проголосовал за ваши комментарии, но это не позволяет мне: /
Размещено как ответ, так что вы можете проголосовать за него! Кстати, с опцией столбца default, вы передаете саму функцию (например, default: shortid.generate) или вызываете ее и по умолчанию используете ее возвращаемое значение (default: shortid.generate())? Если я не ошибаюсь, вам понадобится первое - в противном случае TypeORM будет иметь одно значение по умолчанию при каждом запуске вашего приложения и позволит вставлять одну запись, но затем ошибку с дублированием нарушения ключа для последующих записей.
@Timshel, вы правы, я столкнулся с двойным нарушением ключа. Однако, когда я попробовал рекомендованное вами изменение, я продолжал сталкиваться с ошибкой column "gz68lzqnmn" does not exist (идентификатор меняется каждый раз). Я нашел единственный способ обойти это - оставить default: shortid.generate(), но затем в ловушку BeforeInsert я добавил this.id = shortid.generate(). Очень хакерский и грустный :( но это работает. Если вы хотите глубже изучить это, вы можете вытащить это репо и yarn start для воспроизведения. Никакого давления. Еще раз спасибо! github.com/podverse/podverse-api/tree/primaryDefaultBug
Я почти уверен, что это проблема с цитированием - возвращаемый идентификатор не цитируется, поэтому интерпретируется как столбец. Обернуть shortid.generate() и указать значение в кавычках должно быть все, что нужно - например, default: () => `'${shortid.generate()}'` (обратите внимание на одинарные кавычки вокруг идентификатора).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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