我已将模型定义为
module.exports = function (sequelize, DataTypes) {
const MyModel = sequelize.define('MyModel', {
data: {
type: DataTypes.JSON,
...
},
...
});
return MyModel;
};
我使用
查询它MyModel.findAll().then(myModels => ...);
但是,查询结果中的data
字段是字符串,而不是JSON对象。我该如何解决?
答案 0 :(得分:8)
目前尚不支持MySQL JSON Data Type #4727。但你可以这样做:
module.exports = function (sequelize, DataTypes) {
const MyModel = sequelize.define('MyModel', {
data: {
type: Sequelize.TEXT,
get: function () {
return JSON.parse(this.getDataValue('value'));
},
set: function (value) {
this.setDataValue('value', JSON.stringify(value));
},
,
...
},
...
});
return MyModel;
};
我还在github sequelize-json上找到了这个包你可以尝试一下,如果你不想使用getter和setter。
答案 1 :(得分:3)
由于sequelize现在支持JSON,因此无需使用getter和setter。请参见sequelize api
答案 2 :(得分:1)
MySQL不支持JSON数据类型。
请参阅此处的文档{{3}}
解决方法可能是在查询时使用text和stringify / parse
答案 3 :(得分:1)
Jalal的回答很好,但除非我稍加调整,否则对我不起作用。这是对我有用的东西:
首先:创建一个迁移,该迁移将您想要的字段添加为TEXT
类型。
示例-我想向address
表中添加一个名为Stores
的字段:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn("Stores", "address", Sequelize.TEXT);
},
down: (queryInterface, Sequelize) => {
return queryInterface.removeColumn("Stores", "address");
}
};
下一步: 在模型内部,将具有getter和setter的字段添加到字段和数据类型的列表(对象)中:
address: {
type: DataTypes.TEXT,
get: function() {
return JSON.parse(this.getDataValue("address"));
},
set: function(value) {
return this.setDataValue("address", JSON.stringify(value));
}
},
所以我的整个模型如下:
module.exports = (sequelize, DataTypes) => {
const Store = sequelize.define(
"Store",
{
name: DataTypes.STRING,
isActive: DataTypes.BOOLEAN,
address: {
type: DataTypes.TEXT,
get: function() {
return JSON.parse(this.getDataValue("address"));
},
set: function(value) {
return this.setDataValue("address", JSON.stringify(value));
}
}
},
{}
);
Store.associate = function(models) {
// associations can be defined here
Store.hasMany(models.Order, {
foreignKey: "id",
targetKey: "storeId"
});
};
return Store;
};
现在,您可以创建和检索记录,就像在数据库中使用JSON类型字段一样。
例如:const store = await Store.create({name: "Joe's corner store", address: {address1: "123 test street", city: "Los Angeles", state: "CA"}})
一些注意事项:
在上面的代码块中...
address
。Stores
。return
,否则在尝试创建新记录(Jalal拥有它的方式)时会出错。答案 4 :(得分:0)
最简单的解决方案是使用名为sequelize-json
的小库创建数据库和架构:
var Sequelize = require('sequelize'),
JsonField = require('sequelize-json'),
db,
User;
db = new Sequelize('database', 'username', 'password', {
dialect: 'sqlite',
logging: false
});
User = db.define('User', {
username: Sequelize.STRING,
jsonField: JsonField(db, 'User', 'jsonField')
});
请注意JsonField的参数,您传递了Sequelize实例,模型名称和字段名称。有点笨拙,但这是向模型实例添加适当的钩子所必需的。
现在,您始终可以将该字段视为json对象:
User.create({
username: 'Scott',
jsonField: {
likes: ['running', 'node']
}
})
.then(function(user) {
user.jsonField.likes.push('tests');
return user.save();
})
.then(function(user) {
expect(user.jsonField).to.be.a('object');
expect(user.jsonField.likes).to.have.length(3);
});
答案 5 :(得分:0)
虽然这个问题被标记为 MySQL,但我怀疑一些使用 MariaDB 的人可能会在这里结束,特别是因为 MariaDB 现在在许多地方都是默认的。 MySQL 和 MariaDB 处理 JSON 数据类型的方式有所不同,这就是 sequelize 对这两个 DB 实现不同的原因。
就我而言,我通过将续集显式切换为方言 mariadb
来解决此问题。这要求您安装 mariadb
软件包而不是 mysql2
。之后我的 JSON 列被正确解析为一个对象。