How to set primary key type to UUID via Sequelize CLI

依然范特西╮ 提交于 2020-01-11 19:53:28

问题


I'm creating a DB model via Sequelize CLI with this command:

sequelize model:create --name User --attributes "firstname:string, lastname:string"

This creates the corresponding migration script:

'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');
  }
};

As shown, the primary key is set to integer.

Is there a way to default the CLI to use UUID instead?


回答1:


You'd have to edit the generated file manually, changing Sequelize.INTEGER to Sequelize.UUID, then removing the autoIncrement: true property and include this defaultValue: uuid().

npm install uuid

So your model would look like this:

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');
  }
};

You could also return a function for the defaultValue like so:

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

Another solution would be to add a beforeCreate hook in your model.

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

export default (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    id: {
      allowNull: false,
      primaryKey: true,
      type: Sequelize.UUID
    },
    ...
  }, {});

  User.beforeCreate(user => user.id = uuid());

  return User;
};



回答2:


The last answer will not work because the uuid() function will set a unique default value for all users in your database. Since they are a primaryKey, you will be able to persist only one user in the database, then everyone will receive the same uuid value and, of course, will not be persisted.

So... You have to:

  1. In your migration file, remove autoIncrement: true, and change the type of your id from type: Sequelize.INTEGER to type: Sequelize.UUID
  2. Install the uuid generator function from npm i uuid --save
  3. In your generated User Model, change the beforeCreate function to generate a new uuid before insert it in the database, like this:

    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;
    };
    
  4. Apply the changes of your migration by doing: sequelize db:migrate:undo follow by sequelize db:migrate

  5. Test it.




回答3:


You can modify your migration script with this script

'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');
  }
};

It works for me.




回答4:


You can simple use the type UUIDV4 that comes with Sequelize. Here is more details : UUIDV4

For example making this definition:

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

This is not using the Sequelize CLI but you can use that native UUIDV4 by manually changing that.



来源:https://stackoverflow.com/questions/40734263/how-to-set-primary-key-type-to-uuid-via-sequelize-cli

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!