MySQLのJSONのdata typeをSequelizeで使ってみました。
MySQLのバージョンは5.7.24を使用しています。
テーブル構成
name | type |
---|---|
id | int(11) |
title | varchar(255) |
info | json |
createdAt | datetime |
updatedAt | datetime |
infoの中にはこの様なデータを入れています。
key | val |
---|---|
isbn10 | string |
isbn13 | string |
page | integer |
マイグレーションファイル
JSONのカラムのtypeにはSequelize.JSON
を指定します。
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('Books', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING
},
info: {
type: Sequelize.JSON
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('Books');
}
};
初期データ
id | title | info | createdAt | updatedAt |
---|---|---|---|---|
1 | 青春を山に賭けて | {“page”: 297, “isbn10”: “4167178060”, “isbn13”: “978-4167178062”} | 2019-03-30 17:31:04 | 2019-03-30 17:31:04 |
2 | エベレストを越えて | {“page”: 307, “isbn10”: “4167178052”, “isbn13”: “978-4167178055”} | 2019-03-30 17:31:04 | 2019-03-30 17:31:04 |
3 | 凍 | {“page”: 366, “isbn10”: “4101235171”, “isbn13”: “978-4101235172”} | 2019-03-30 17:31:04 | 2019-03-30 17:31:04 |
検索
JSONデータ内のisbn10
に対して検索してみます。
db.Book.findOne({where: {
"info.isbn10": "4167178060"
}
}).then((books)=>{
console.log(books.dataValues)
}).then(()=>{
db.sequelize.close()
})
SQL
SELECT `id`, `title`, `info`, `createdAt`, `updatedAt` FROM `Books` AS `Book` WHERE (`Book`.`info`->>'$."isbn10"') = '4167178060' LIMIT 1;
実行結果
{ id: 1,
title: '青春を山に賭けて',
info:
{ page: 297, isbn10: '4167178060', isbn13: '978-4167178062' },
createdAt: 2019-03-30T08:31:04.000Z,
updatedAt: 2019-03-30T08:31:04.000Z }
JSONのカラムはdictionary形式で返ってくるのでこのようにアクセスできます。
books.dataValues.info.page // 297
特定の値のみ更新
JSONデータのアップデート時は以下のように実行すると他のJSONデータが消えてしまうので
db.Book.update({
"info.isbn10": "xxxxx"
}, {
where: {id: 1}
}).then(()=>{
db.sequelize.close()
})
このように指定してMySQLのJSON_SET
関数を呼び出して指定の項目のみ更新します。
db.Book.update({
info: db.sequelize.fn("JSON_SET", db.sequelize.col("info"), "$.isbn", "xxxxx")
}, {
where: {id: 1}
}).then(()=>{
db.sequelize.close()
})
SQL
UPDATE `Books` SET `info`=JSON_SET(`info`, '$.isbn', 'xxxxx'),`updatedAt`=? WHERE `id` = ?
実行後データ
id | title | info | createdAt | updatedAt |
---|---|---|---|---|
1 | 青春を山に賭けて | {“page”: 297, “isbn10”: “xxxxx”, “isbn13”: “978-4167178062”} | 2019-03-30 17:31:04 | 2019-03-30 20:31:45 |
2 | エベレストを越えて | {“page”: 307, “isbn10”: “4167178052”, “isbn13”: “978-4167178055”} | 2019-03-30 17:31:04 | 2019-03-30 17:31:04 |
3 | 凍 | {“page”: 366, “isbn10”: “4101235171”, “isbn13”: “978-4101235172”} | 2019-03-30 17:31:04 | 2019-03-30 17:31:04 |
削除
検索の場合と同じように指定できます。
db.Book.destroy({
where: {"info.isbn10": "xxxxx"}
}).then(()=>{
db.sequelize.close()
})
SQL
DELETE FROM `Books` WHERE (`info`->>'$."isbn10"') = 'xxxxx'
実行後データ
id | title | info | createdAt | updatedAt |
---|---|---|---|---|
2 | エベレストを越えて | {“page”: 307, “isbn10”: “4167178052”, “isbn13”: “978-4167178055”} | 2019-03-30 17:31:04 | 2019-03-30 17:31:04 |
3 | 凍 | {“page”: 366, “isbn10”: “4101235171”, “isbn13”: “978-4101235172”} | 2019-03-30 17:31:04 | 2019-03-30 17:31:04 |