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

时间:2016-11-22 05:17:52

标签: sequelize-cli

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

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

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

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

如图所示,主键设置为integer

有没有办法让CLI默认使用UUID

12 个答案:

答案 0 :(得分:12)

您必须手动编辑生成的文件,将Sequelize.INTEGER更改为Sequelize.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');
  }
};

您还可以返回defaultValue的函数,如下所示:

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

另一种解决方案是在模型中添加beforeCreate挂钩。

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

答案 1 :(得分:9)

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

所以...您必须:

  1. 在您的迁移文件中,删除autoIncrement: true,并将ID的类型从type: Sequelize.INTEGER更改为type: Sequelize.UUID
  2. npm i uuid --save安装uuid生成器功能
  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;
    };
    
  4. 通过执行以下操作来应用迁移的更改:sequelize db:migrate:undo,然后跟随sequelize db:migrate

  5. 测试它。

答案 2 :(得分:3)

如果您需要让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()'),
},

答案 3 :(得分:2)

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

answer from @Ismael Terreno是真实的;但是,有一个我没有经验丰富的错误可以解释:如果您的模型在使用sequelize提供的示例时包含该格式,将无法正常工作。即使这样,您也无需在续集之外导入UUID。您仍然可以利用sequelize提供它的优势,但是由于某些原因您必须这样做:

"use strict";
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define(
    "User",
    {
      id: {
        primaryKey: true,
        type: DataTypes.UUID,
        defaultValue: require("sequelize").UUIDV4
      },
    {}
  );
  User.associate = function(models) {
    //enter associations here
    });
  };
  return User;
};`

我对此进行了测试并成功了,但是由于之前的成功,我才发现了这一点,因为我很早就对模型进行了如下设置,在定义模型之前,我需要进行所有操作:

const { Sequelize, DataTypes, Model } = require("sequelize");
const db = require("../../config/database");

const userModel = db.define("users", {
  id: {
    type: DataTypes.UUID,
    defaultValue: Sequelize.UUIDV4,
    primaryKey: true
  }
});

答案 4 :(得分:2)

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

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

PS:在v5.x上续集

迁移

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

模型

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;

控制器

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`,
    });
  }

答案 5 :(得分:2)

简单地为所有数据库工作

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

   id: {
      type: DataTypes.UUID,
      unique: true,
      primaryKey: true,
      isUUID: 4,
      defaultValue: uuidv4()
    },

答案 6 :(得分:2)

确保您的package.json已更新uuid模块

"uuid": "^8.2.0",

这是我的问题,因为之前是3.4.0,而续集对此不起作用。

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

在MySQL上升级uuid软件包后,此方法就可以正常工作

别忘了将导入更改为

const { v4: uuid } = require('uuid')

经过"sequelize": "^5.21.13"

的测试

答案 7 :(得分:1)

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

'use strict';
module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        defaultValue: Sequelize.literal('uuid_generate_v1()'),
        type: Sequelize.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');
  }
};

对我有用。

答案 8 :(得分:1)

我尝试了很多选择,结果一切都非常简单。试试这个

型号:

import { Model, DataTypes } from 'sequelize';
import { v4 as uuidv4 } from 'uuid';

import sequelize from '..';

class User extends Model {}

User.init(
  {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      allowNull: false,
      defaultValue: () => uuidv4(),
    }
  },
  {
    sequelize,
    tableName: 'user',
    timestamps: false,
  },
);

export default User;

迁移:

    const { v4: uuidv4 } = require('uuid');

module.exports = {
  up: async (queryInterface, DataTypes) => {
    await queryInterface.createTable('user', {
      id: {
        type: DataTypes.UUID,
        primaryKey: true,
        allowNull: false,
        defaultValue: uuidv4(),
      }
    });
  },

  down: async queryInterface => {
    await queryInterface.dropTable('user');
  },
};

答案 9 :(得分:0)

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

例如,进行以下定义:

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

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

答案 10 :(得分:0)

  • 没有自动增量。 UUID 是随机生成的。
  • 确保您使用 DataType.UUID 并将默认值设为 UUIDV4

没有自动增量。生成 UUID

export const User = db.define('user',
    {
        id: {
            type: DataTypes.UUID,
            defaultValue: DataTypes.UUIDV4,
            primaryKey: true,
        },

答案 11 :(得分:0)

对于使用 Postgres 指定 v6.5.0 的续集 defaultValue: Sequelize.UUIDV4 不起作用。相反,我不得不这样做:

'use strict';

module.exports = {
  up: async (queryInterface, Sequelize) => {

      await queryInterface.sequelize.query('CREATE EXTENSION IF NOT EXISTS "uuid-ossp";')
      await queryInterface.addColumn('MyTable', 'id', {
        type: Sequelize.UUID,
        defaultValue: Sequelize.literal('uuid_generate_v4()'),
        allowNull: false,
        primaryKey: true
      })

  },
  down: async (queryInterface, Sequelize) => {

  }
};