web-dev-qa-db-ja.com

Sequelize CLIを介してプライマリキータイプをUUIDに設定する方法

このコマンドで Sequelize CLI を介してDBモデルを作成しています:

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を使用する方法はありますか?

11
rtorres

生成されたファイルを手動で編集し、_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;
};
_
14
John Kennedy

uuid()関数はデータベース内のすべてのユーザーに一意のデフォルト値を設定するため、最後の答えは機能しません。これらはprimaryKeyであるため、データベース内で永続化できるのは1人のユーザーのみです。そうすると、全員が同じ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:undosequelize db:migrate

  5. 試して。

このスクリプトで移行スクリプトを変更できます

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

わたしにはできる。

3
jennndol

Sequelizeに付属しているUUIDV4型を簡単に使用できます。詳細は次のとおりです。 IDV4

たとえば、次のように定義します。

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

これはSequelize CLIを使用していませんが、手動で変更することでそのネイティブUUIDV4を使用できます。

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

@ Ismael Terrenoからの回答 はtrueです。ただし、説明が不十分なバグがあります。sequelizeから提供された例を使用しているときにモデルにその形式が含まれている場合、機能しません。それでも、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
  }
});
0
Emanuel Siu

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()'),
},
_
0
Emma Paulowicz