Node.js Sequelize UUID 主键 + Postgres

Posted

技术标签:

【中文标题】Node.js Sequelize UUID 主键 + Postgres【英文标题】:Node.js Sequelize UUID primary key + Postgres 【发布时间】:2018-10-29 02:33:13 【问题描述】:

我尝试使用 sequelize 创建数据库模型,但我遇到了模型主键的问题。

设置

我在 docker 容器中使用 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 执行下一个表达式:

执行(默认):从“货币”中选择“id”、“uuid”、“name”、“ticker”、“alt_tickers”、“createdAt”、“updatedAt”作为“货币”按“货币”排序。 "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 列的列? 可能导致此错误的原因以及应如何解决?

提前致谢!

【问题讨论】:

【参考方案1】:

您没有在此处发布的是您的model 代码。这就是我认为发生的事情

    数据库已手动从id更改为uuid。 您的模型未反映此更改。

因此查询同时搜索iduuid

您可以像下面这样在您的模型中修复我定义的 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);
  ));

【讨论】:

其实模型一开始就变了。我也尝试回滚到整数“id”,但数据库中没有设置主键。 当然。看看吧。 模型还显示id字段?它应该是uuid。您还应该将其设为主键 primaryKey: true 我提供了两个案例。第一个是 uuid 为 UUID 数据类型的表,第二个是 id 为 UUID 数据类型的表,因此提供了两个模型,一个接一个。如果我理解你是正确的,你希望我为迁移添加一个主键,但这已经完成了。 主键的模型和数据库声明应该独立发生并推荐。因此,如果您正在解决“错误:将名为“id”的列添加到“货币”的属性中,则应将其设为模型和数据库中的主键,因为查询是由 Sequelize 生成的【参考方案2】:

这几乎是我在网上找到的唯一资源,它解释了如何设置 数据库 为其提供默认值的 UUID 列,而不依赖第三方 uuid npm 包:https://krmannix.com/2017/05/23/postgres-autogenerated-uuids-with-sequelize/

短版:

    您需要使用 sqlz 迁移安装“uuid-ossp”postgres 扩展 定义表时,使用这个defaultValue:Sequelize.literal( 'uuid_generate_v4()' )

【讨论】:

以上是关于Node.js Sequelize UUID 主键 + Postgres的主要内容,如果未能解决你的问题,请参考以下文章

节点的 Sequelize 不允许在主键上自动生成 UUID *除非*字段名称是 'id'

尝试将行插入表因为带有sequelize.js的UUID外键时出错

node.js后端之sequelize

多张图片 + Node.js + Sequelize + Mysql

Node.js - 如何使用 Sequelize 交易

Node.js / Sequelize.js / Express.js - 如何插入多对多关联? (同步/异步?)