sequelizeでidに0が入ってしまう
sequelizeでidに0が入ってしまう
環境
- MariaDB 10.1.9 (Homebrew)
概要
SequelizeでdialectとしてMySQLをした際に、 AUTO_INCREMENTカラムを含むテーブルに対してINSERTすると0が入ってしまう可能性がある。
Sequelize
SequelizeはNode.js用のORMである。
まず、下記のようなテーブルがあるとする
CREATE TABLE `Users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ここで、sequelizeで定義したModelからnameカラムのみを指定してinsertすると 下記のようなSQLが発行される
INSERT INTO `Users` (`id`,`name`) VALUES (DEFAULT,'sequelize');
この時、設定によってはUsersに追加されるレコードは下記のようなものになる場合がある
select * from Users; +----+-----------+ | id | name | +----+-----------+ | 0 | sequelize | +----+-----------+
NO_AUTO_VALUE_ON_ZERO
https://dev.mysql.com/doc/refman/5.6/ja/faqs-sql-modes.html
sql_modeの1つにNO_AUTO_VALUE_ON_ZEROがあり、 これを設定すると、INSERT時にAUTO_INCREMENTカラムに対して0を指定しても自動採番されなくなります。
NO_AUTO_VALUE_ON_ZERO は AUTO_INCREMENT カラムの処理に影響します。通常は、NULL または 0 をカラムに挿入することによって、カラムの次のシーケンス番号を生成します。NO_AUTO_VALUE_ON_ZERO は 0 のこの動作を抑制するため、NULL のみが次のシーケンス番号を生成します。
https://dev.mysql.com/doc/refman/5.6/ja/sql-mode.html
また、MySQLでは数値型の初期値は0なので、DEFAULTは0にります。 https://dev.mysql.com/doc/refman/5.6/ja/data-type-defaults.html
なので、NO_AUTO_VALUE_ON_ZEROを設定している状態でidに対してDEFAULTを指定すると 必ずidに0が入るようになってしまいます。
対応
下記SQLでsql_modeを確認、設定することができます。 状況に応じて、適切なsql_modeを設定すれば良さそう?
SELECT @@GLOBAL.sql_mode; SELECT @@SESSION.sql_mode; SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION'; SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
まとめ
Sequelizeを使うときは、sql_modeの設定を事前に確認しましょう。 MySQLに対しての知識が全然ないので、地味にハマりました。。。