如何通过Sequelize CLI将主键类型设置为UUID

rto*_*res 9 sequelize-cli

我正在使用此命令通过Sequelize CLI创建数据库模型:

sequelize model:create --name User --attributes "firstname:string, lastname:string"
Run Code Online (Sandbox Code Playgroud)

这将创建相应的迁移脚本:

'use strict';
module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      firstname: {
        type: Sequelize.STRING
      },
      lastname: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: function(queryInterface, Sequelize) {
    return queryInterface.dropTable('Users');
  }
};
Run Code Online (Sandbox Code Playgroud)

如图所示,主键设置为integer.

有没有办法默认使用CLI UUID

小智 25

您可以简单地使用 Sequelize 附带的 UUIDV4 类型。这是更多详细信息: UUIDV4

例如制定这个定义:

id: {
  type: Sequelize.UUID,
  defaultValue: Sequelize.UUIDV4,
  allowNull: false,
  primaryKey: true
}
Run Code Online (Sandbox Code Playgroud)

这不是使用 Sequelize CLI,但您可以通过手动更改它来使用本机 UUIDV4。

  • 这个答案被严重低估了。它比涉及指定 beforeCreate 挂钩、迁移脚本等的任何事情都简单/更好。这是最简单的答案,而且它只是简单的工作。(我一直在尝试使用 set(value) 函数来设置它。)我相信你也许可以制作这个 CLI。我认为您可以设置某些像这样简单的属性。 (3认同)
  • 根据您使用的sequelize版本,以及如果您使用postgres,这可能不起作用。如果您使用 postgres 的后续版本的更高版本,我建议使用 `uuid-ossp` 扩展 (2认同)

Joh*_*edy 14

您必须手动编辑生成的文件,更改Sequelize.INTEGERSequelize.UUID,然后删除autoIncrement: true属性并包含此属性defaultValue: uuid().

npm install uuid

所以你的模型看起来像这样:

const uuid = require('uuid/v4'); // ES5

'use strict';

module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: uuid()
      },
      firstname: {
        type: Sequelize.STRING
      },
      lastname: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: function(queryInterface, Sequelize) {
    return queryInterface.dropTable('Users');
  }
};
Run Code Online (Sandbox Code Playgroud)

你也可以返回一个defaultValue类似的功能:

      id: {
        allowNull: false,
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: () => uuid()
      },
Run Code Online (Sandbox Code Playgroud)

  • 这能按预期工作吗?我尝试了此操作,并在第一次尝试中正确添加了UUID。添加第二条记录时,我收到一条错误消息,说UUID已经存在。因此,我认为uuid()行仅运行一次,并且对所有记录都设置为相同 (2认同)
  • 返回`()=> uuid()`到defaultValue解决了我在mysql数据库中的问题。 (2认同)

Wag*_*rin 10

最后一个答案不起作用,因为该uuid()函数将为数据库中的所有用户设置唯一的默认值.由于它们是primaryKey,因此您只能在数据库中保留一个用户,然后每个人都将收到相同的uuid值,当然,不会保留.

所以......你必须:

  1. 在迁移文件,删除autoIncrement: true,和更改ID的类型type: Sequelize.INTEGERtype: Sequelize.UUID
  2. 从中安装uuid生成器功能 npm i uuid --save
  3. 在生成的用户模型中,更改beforeCreate函数以在将其插入数据库之前生成新的uuid,如下所示:

    const uuid = require('uuid/v4');
    /*...*/
    module.exports = (sequelize, DataTypes) => {
      const User = sequelize.define('User', {
        /* Your User Model Here */
      }, {});
      User.beforeCreate((user, _ ) => {
        return user.id = uuid();
      });
      return User;
    };
    
    Run Code Online (Sandbox Code Playgroud)
  4. 通过执行sequelize db:migrate:undo以下操作来应用迁移的更改:sequelize db:migrate

  5. 测试一下.


Lut*_*hfi 9

您可以使用此脚本修改迁移脚本

'use strict';
module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('Users', {
      id: {
        primaryKey: true,
        type: Sequelize.UUID,
        defaultValue: Sequelize.literal('uuid_generate_v4()')
      },
      firstname: {
        type: Sequelize.STRING
      },
      lastname: {
        type: Sequelize.STRING
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: function(queryInterface, Sequelize) {
    return queryInterface.dropTable('Users');
  }
};
Run Code Online (Sandbox Code Playgroud)

这个对我有用。

  • 如果您的数据库执行过以下 sql 命令,那么这将起作用:CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; 也就是说,如果您使用 Postgresql。 (2认同)

小智 8

  • 无自动增量。UUID 是随机生成的。
  • 确保您使用DataType.UUID默认值UUIDV4

无自动增量。UUID 已生成

export const User = db.define('user',
    {
        id: {
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
            primaryKey: true,
        },
Run Code Online (Sandbox Code Playgroud)


gbs*_*tos 6

上面提到的任何解决方案都不适合我。但对于我自己解决问题很有帮助。

我使用 ES6+ 语法并通过以下方式解决:

PS:在 v5.x 上进行 Sequelize

移民

'use strict';

module.exports = {
  up: (queryInterface, Sequelize) => {
    return queryInterface.createTable('users', {
      id: {
        type: Sequelize.UUID,
        primaryKey: true,
        allowNull: false,
        defaultValue: Sequelize.UUIDV4,
      },
      name: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      created_at: {
        type: Sequelize.DATE,
        allowNull: false,
      },
      updated_at: {
        type: Sequelize.DATE,
        allowNull: false,
      }
    });
  },

  down: (queryInterface) => {
    return queryInterface.dropTable('users');
  }
}

Run Code Online (Sandbox Code Playgroud)

模型

import { uuid } from 'uuidv4';
import Sequelize, { Model } from 'sequelize';

class User extends Model {
  static init(sequelize) {
    super.init(
      {
        name: Sequelize.STRING,
      },
      {
        sequelize,
      }
    );

    this.addHook('beforeSave', async (user) => {
      return user.id = uuid();
    });

    return this;
  }
}

export default Users;

Run Code Online (Sandbox Code Playgroud)

控制器

import User from '../models/User';

class UserController {
  async store(request, response) {
    const { user } = request.body;

    const { id, name } = await User.create(users);

    return response.json({
      id,
      message: `User ${name} was register successful`,
    });
  }
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您需要让 Postgres 在插入时生成 UUID 作为默认值,则此方法defaultValue: Sequelize.UUIDV4不起作用。不管怎样,Sequelize 会生成 NULL 值。

相反,Sequelize.literal('uuid_generate_v4()')必须使用。这将产生查询CREATE TABLE IF NOT EXISTS "table" ("id" UUID NOT NULL DEFAULT uuid_generate_v4())

id: {
    allowNull: false,
    primaryKey: true,
    type: Sequelize.DataTypes.UUID,

    defaultValue: Sequelize.literal('uuid_generate_v4()'),
},
Run Code Online (Sandbox Code Playgroud)