'How to set primary key type to UUID via Sequelize CLI

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?



Solution 1:[1]

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.

Solution 2:[2]

You'd have to edit the generated file manually, changing Sequelize.INTEGER to Sequelize.UUID, then remove the autoIncrement: true.

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
      },
      /* Other model properties */
    });
  },
  down: function(queryInterface, Sequelize) {
    return queryInterface.dropTable('Users');
  }
};

Update your beforeCreate hook as follows:

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

This assumes you are using Sequelize v4.

Solution 3:[3]

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.

Solution 4:[4]

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.

Solution 5:[5]

Any of the solutions mentioned above did not work for me. But was much helpful to arrive on my own resolution of the problem.

I'm using ES6+ syntax and solved this way:

PS: Sequelize on v5.x

Migration

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

Model

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;

Controller

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

Solution 6:[6]

If you need to make Postgres generate UUID on the insert as a default value, this approach defaultValue: Sequelize.UUIDV4 would not work. Anyway, Sequelize generates NULL value.

Instead, Sequelize.literal('uuid_generate_v4()') must be used. That shall produce query 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()'),
},

Solution 7:[7]

  • No auto increment. UUID are randomly generated.
  • Ensure you use DataType.UUID and default value to UUIDV4

No Auto increment. UUID are generated

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

Solution 8:[8]

I tried many options, everything turned out to be very simple. Try like this

Model:

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;

Migration:

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

Solution 9:[9]

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

The answer from @Ismael Terreno is true; however, there is a bug that I'm not experienced enough to explain: if your model contains that format while using the examples provided from sequelize it will NOT work. Even so, you don't need to import UUID outside of sequelize; you can still take advantage of sequelize providing it, but you have to require it in for some reason like so:

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

I tested that and it worked, but I only found this out because of a previous success I had early on where my set up looked like this for the model, where I required everything before defining the model:

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

Solution 10:[10]

Make sure your package.json has updated uuid module

"uuid": "^8.2.0",

This was the problem in my case as it was 3.4.0 before and sequelize does not work with that.

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

This works just fine after the uuid package upgrade on MySQL

Don't forget to change your imports to

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

Tested on "sequelize": "^5.21.13"

Solution 11:[11]

simply and work for all databases

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

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

Solution 12:[12]

For sequelize v6.5.0 using Postgres specifying defaultValue: Sequelize.UUIDV4 did not work. Instead I had to do this:

'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) => {

  }
};

Solution 13:[13]

To set the default value in migration you will need to write like this

id: {
      primaryKey: true,
      allowNull: false,
      defaultValue: Sequelize.literal("gen_random_uuid()"),
      type: Sequelize.UUID,
    },