我正在创建一个用于存储用户会话的表。我将使用以下方法将IP地址存储为整数:IP-addresses stored as int results in overflow?
我想为IP字段指定一个getter和setter,以便它可以在IP和int之间自动转换。
不幸的是我收到以下错误,我不知道发生了什么。我一直试图修复它几个小时,谷歌没有给我带来任何结果:
RangeError: Maximum call stack size exceeded
型号:
model = db.define(name, {
id: {type: Sequelize.STRING, allowNull: false, primaryKey: true},
ipAddress: {type: Sequelize.INTEGER(11).UNSIGNED, allowNull: false},
userAgent: {type: Sequelize.STRING, allowNull: false},
username: {type: Sequelize.STRING, allowNull: false},
password: {type: Sequelize.STRING, allowNull: false},
firstName: {type: Sequelize.STRING, allowNull: false},
lastName: {type: Sequelize.STRING, allowNull: false},
email: {type: Sequelize.STRING}
}, {
getterMethods: {
name: function() { return this.firstName + this.lastName },
ipAddress: function() {
ip = this.getDataValue("ipAddress");
return ((ip >> 24) & 255) + "." + ((ip >> 16) & 255) + "." + ((ip >> 8) & 255) + "." + (ip & 255);
}
},
setterMethods: {
ipAddress: function(ip) {
var parts = ip.split(".");
var ret = 0;
ret += parseInt(parts[0], 10) << 24;
ret += parseInt(parts[1], 10) << 16;
ret += parseInt(parts[2], 10) << 8;
ret += parseInt(parts[3], 10);
return ret;
}
}
});
插入IP:
model.findOrCreate({id: sessionId}, {
id: sessionId,
ipAddress: req.ip, // === "192.168.1.79"
userAgent: req.get("user-agent"),
username: "test",
password: "test",
firstName: "first",
lastName: "last",
email: "email"
})
我可以确认getter / setter代码是否按照需要转换,但它在Sequelize中无法正常运行。
答案 0 :(得分:4)
我也和Sequelize一起遇到了这个问题。我正在阅读并重新阅读官方文档,搜索我知道要在互联网上搜索的所有内容,我终于在这里结束了。一旦我找到你的问题,没有答案,我决定搜索Sequelize本身的源代码。果然,我找到了答案!
如果您查看Sequelize源代码中的文件sequelize/test/dao-factory.test.js
,您将发现潜伏在测试用例中的以下代码:
setterMethods: {
price1: function(v) { this.setDataValue('price1', v * 100) }
},
我复制了上面的语法,在我自己的setter方法中使用它,它可以工作!
他们真的应该更新sequelize网站上的文档..嗯..也许我应该考虑帮助他们解决这个问题?无论如何,祝你好运!
答案 1 :(得分:1)
我不知道是否有人仍在运行此错误,但如果你遇到麻烦,我就是如何解决这个问题。
我有一个类似的情况,我有一个UserModel对象,看起来像这样:
var UserModel = sequelize.define("users", {
ID: {
type: Sequelize.INTEGER,
field: "ID",
primaryKey: true,
autoIncrement: true
},
Username: {
type: Sequelize.STRING,
field: "Username"
},
Password: {
type: Sequelize.STRING,
field: "Password"
},
Sector: {
type: Sequelize.INTEGER,
field: "Sector"
},
SubSector: {
type: Sequelize.INTEGER,
field: "SubSector"
},
Email: {
type: Sequelize.STRING,
field: "email"
},
Status: {
type: Sequelize.INTEGER,
field: "status"
}
}
我的主持人和吸气者是:
{
getterMethods: {
Sector: function() {
return this.Sector;
},
Status: function() {
return this.Status;
}
},
setterMethods: {
Sector: function(val) {
this.setDataValue('Sector',val);
},
Status: function(val) {
this.setDataValue('Status',val);
}
}
});
当然我有堆栈错误。
为了解决这个问题,我刚刚改变了我的二传手和吸气者:
{
getterMethods: {
currSector: function() {
return this.Sector;
},
currStatus: function() {
return this.Status;
}
},
setterMethods: {
newSector: function(val) {
this.setDataValue('Sector',val);
},
newStatus: function(val) {
this.setDataValue('Status',val);
}
}
});
一切都神奇地好了,尽管在网上有很多例子,我看到人们建议提供与字段相同的setter / getters名称的方法。
因此,简而言之,更改为setter和getters名称,以便他们的名称不匹配任何已定义的字段解决了我的问题。好的做法?我不确定,但它解决了我的问题。
答案 2 :(得分:1)
我有类似的情况,我以这种方式解决
const ProductImages = db.define('product_images', {
product_image_id: {type: Sequelize.INTEGER, primaryKey: true,
autoIncrement: true},
url: Sequelize.TEXT,
product_id: Sequelize.INTEGER,
is_primary: Sequelize.INTEGER,
}, {
timestamps: false,
getterMethods: {
is_primary() {
return parseInt(this.dataValues.is_primary)
},
},
scopes: {
byDefault() {
return {
include: [{
model: ProductDescriptions, as:
'product_description', where: {language_id: 1}
}]
};
},
}
})
module.exports = ProductImages;
当我调用this.davaValues.column_name时,它不会为该列调用recoursive getterMethod