Node.js Sequelize UUID первичный ключ + Postgres - PullRequest
0 голосов
/ 18 мая 2018

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

Настройка

Я использую Postgres (v10) в контейнере Docker и секвализирую (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 (по умолчанию): ВЫБЕРИТЕ «id», «uuid», «name», «ticker», «alt_tickers», «creationAt», «updatedAt» FROM «Валюты» AS «Валюта» ORDER BY «Валюта». «id» ASC;

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

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

  ...      
  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;
};

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

Ошибка: в атрибуты «Валюты» добавлен столбец «id», но не помечен «primaryKey: true»

Вопросы

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

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

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

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

Короткая версия:

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

То, что вы не разместили здесь, это ваш 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.log(user);
  }));
...