在 MySql 数据库中将 primaryKey 续集为 UUID - 不起作用

Posted

技术标签:

【中文标题】在 MySql 数据库中将 primaryKey 续集为 UUID - 不起作用【英文标题】:Sequelize primaryKey as UUID in MySql database - not working 【发布时间】:2018-09-26 15:08:15 【问题描述】:

我在使用主键作为 uuid 的 Sequalize 中遇到了实现模型的问题。我一步一步地按照所有说明进行操作,但仍然无法解决。

这是我的模型的样子:

'use strict';
module.exports = (sequelize, DataTypes) => 
  var Todo = sequelize.define('Todo', 
    title: DataTypes.STRING,
    description: DataTypes.STRING,
    test: DataTypes.UUID
  , );
  Todo.associate = function(models) 
    // associations can be defined here
  ;
  return Todo;
;

以及迁移文件:

'use strict';
module.exports = 
  up: (queryInterface, Sequelize) => 
    return queryInterface.createTable('Todos', 
      id: 
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV1
      ,
      title: 
        type: Sequelize.STRING
      ,
      description: 
        type: Sequelize.STRING
      ,
      test: 
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4
      ,
      createdAt: 
        allowNull: false,
        type: Sequelize.DATE
      ,
      updatedAt: 
        allowNull: false,
        type: Sequelize.DATE
      
    );
  ,
  down: (queryInterface, Sequelize) => 
    return queryInterface.dropTable('Todos');
  
;

调用 post 方法创建元素后,我在 ID 列中得到了一个空值,在 test 列中得到了 NULL...

数据库是 mysql

还有其他方法吗?

【问题讨论】:

【参考方案1】:

1) 在 Sequelize 中设置自定义键

我在 Sequalize 中遇到了实现模型的问题 主键为 uuid。

默认情况下,如果您的模型包含带有primaryKey: true 的密钥,则sequelize 假定一个名为INTEGER 的PK 类型为id

在您的情况下,您似乎希望制作自己的自定义 PK。

在您的模型中使用以下

var Todo = sequelize.define('Todo', 
    id: 
      primaryKey: true,
      type: DataTypes.UUID
    
    // rest of properties
 );

2) 验证

在调用 post 方法创建元素后,我在 ID 列中得到了一个空值,在 test 列中得到了 NULL...

没有太多关于您的查询以及如何为数据库播种的信息,很难具体回答。

但是,test 列是 null 我并不感到惊讶,因为您没有列出任何验证。因此,如果您播种/创建未设置 test 值的行,它将是 null

要创建验证,请执行以下操作

型号:

var Todo = sequelize.define('Todo', 
    // rest of properties
    test: 
      allowNull: false
      type: DataTypes.UUID,
      validate: 
        notNull: true
      
    
);

迁移:

queryInterface.createTable('Todos', 
    // rest of properties
    test: 
      allowNull: false,
      type: Sequelize.UUID,
      defaultValue: Sequelize.UUIDV4
    
);

3) 保持模型和迁移同步

(请参阅:https://***.com/a/49796801/8954866)在sequelize 中,模型和迁移不会自动彼此同步,除非最初使用sequelize-cli model:generate 生成。我不确定您是运行迁移还是在针对模型的单元测试中运行查询。但是你必须确保它们是同步的。一个主要的例子是,在上述情况下,您的迁移说 idUUID 类型,但您的模型会认为它是 INTEGER 类型。

参考文献

Setting Custom Primary Keys Validations and allowNull

【讨论】:

我的代码中有这个。这样做的问题是它不会转换为数据库中具有 UUID 默认值的 ID 列。默认情况下,如果我直接插入一行(使用数据库客户端),它会将其保留为 null。 Sequelize 应该在数据库级别设置一个默认值,以防用户不使用 API。【参考方案2】:

确保您的 package.json 已更新 uuid 模块,这就是我的问题。

accessSecret: 
      type: DataTypes.UUID,
      defaultValue: Sequelize.UUIDV4,
      allowNull: false,
      unique: true,
    ,

这很好用, 只要确保 package.json 有

"uuid": "^8.2.0",

【讨论】:

为什么?我认为 MySQL 本身有 UUID 类型

以上是关于在 MySql 数据库中将 primaryKey 续集为 UUID - 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

mysql之字段约束-第五篇

mysql之字段约束-第五篇

在oracle存储过程中将数据插入到多个表中

mysql中key primary key unique key 与index区别

如何在 SQL 中将多个数据库表中的数据组合成一个结果表

mysql中key和primary key的区别