Node.js Sequelize первичный ключ UUID + Postgres

Я пытаюсь создать модель базы данных с помощью sequelize, но у меня проблема с первичным ключом модели.

Параметр

Я использую Postgres (v10) в контейнере докеров и sequalize (Node.js v10.1.0 ) для моделей и GraphQL (0.13.2) + GraphQL-Sequalize (8.1.0) для обработки запросов.

Проблема

После создания моделей с помощью sequelize-cli у меня вручную попытался заменить столбец id на uuid. Вот моя модель миграции, которую я использую.

'use strict';
const DataTypes = require('sequelize').DataTypes;

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('Currencies', {
      uuid: {
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: DataTypes.UUIDV4,
        allowNull: false
      },
      name: {
        type: Sequelize.STRING
      },
      ticker: {
        type: Sequelize.STRING
      },
      alt_tickers: {
        type: Sequelize.ARRAY(Sequelize.STRING)
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: (queryInterface, Sequelize) => {
    return queryInterface.dropTable('Currencies');
  }
};

Модель:

'use strict';
module.exports = (sequelize, DataTypes) => {
    const Currency = sequelize.define('Currency', {
        uuid: DataTypes.UUID,
        name: DataTypes.STRING,
        ticker: DataTypes.STRING,
        alt_tickers: DataTypes.ARRAY(DataTypes.STRING)
    }, {});
    Currency.associate = function(models) {
        // associations can be defined here
    };
    return Currency;
};

Из-за некоторой проблемы sequalize выполняет следующее выражение:

Executing (default): SELECT "id", "uuid", "name", "ticker", "alt_tickers", "createdAt", "updatedAt" FROM "Currencies" AS "Currency" ORDER BY "Currency"."id" ASC;

Это приводит к ошибке «идентификатор столбца не существует».

В качестве альтернативы я попытался исправить это, переименовав столбец uuid в я бы при миграции:

  ...      
  id: {
      allowNull: false,
      primaryKey: true,
      type: Sequelize.UUID,
      defaultValue: Sequelize.UUIDV4()
  },
  ... 

А у модели:

'use strict';
module.exports = (sequelize, DataTypes) => {
    const Currency = sequelize.define('Currency', {
        id: DataTypes.INTEGER,
        name: DataTypes.STRING,
        ticker: DataTypes.STRING,
        alt_tickers: DataTypes.ARRAY(DataTypes.STRING)
    }, {});
    Currency.associate = function(models) {
        // associations can be defined here
    };
    return Currency;
};

но результатом была следующая ошибка при запуске программы:

Error: A column called 'id' was added to the attributes of 'Currencies' but not marked with 'primaryKey: true'

Вопросов

  • Итак, есть ли способ заставить sequelize использовать UUID в качестве первичного ключа таблицы без определения столбца id?
  • Есть ли способ создать столбцы без столбцов идентификаторов?
  • Что могло вызвать эти ошибки и как их исправить?

Заранее спасибо!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
15 238
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

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

  1. База данных была вручную изменена с id на uuid.
  2. Ваша модель не отражает это изменение.

Следовательно, запрос ищет как id, так и uuid.

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

const User = sequelize.define('user', {
  uuid: {
    type: Sequelize.UUID,
    defaultValue: Sequelize.UUIDV1,
    primaryKey: true
  },
  username: Sequelize.STRING,
});

sequelize.sync({ force: true })
  .then(() => User.create({
    username: 'test123'
  }).then((user) => {
    console.info(user);
  }));

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

Number16BusShelter 19.05.2018 14:58

Конечно. Взглянуть.

Number16BusShelter 19.05.2018 15:40

Модель по-прежнему показывает поле id? это должен быть uuid. Вы также должны сделать его первичным ключом primaryKey: true

AbhinavD 19.05.2018 15:56

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

Number16BusShelter 19.05.2018 16:08

Объявление первичного ключа в модели и БД должно происходить независимо и рекомендуется. Поэтому, если вы решаете `Ошибка: столбец с именем 'id' был добавлен к атрибутам 'Currencies', вы должны сделать его первичным ключом в модели, а также в базе данных, поскольку запрос генерируется Sequelize

AbhinavD 19.05.2018 16:14

Хорошо, теперь я понял. Большое спасибо.

Number16BusShelter 19.05.2018 16:25

Это практически единственный ресурс, который я нашел в Интернете, который объясняет, что нужно для настройки столбца UUID, для которого база данных предоставляет значения по умолчанию, не полагаясь на сторонний пакет uuid npm: https://krmannix.com/2017/05/23/postgres-autogenerated-uuids-with-sequelize/

Укороченная версия:

  1. Вам нужно будет установить расширение postgres "uuid-ossp", используя миграцию sqlz.
  2. При определении таблицы используйте этот defaultValue: Sequelize.literal( 'uuid_generate_v4()' )

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