Node.js Sequelize getter / setter RangeError

时间:2013-08-05 00:52:46

标签: javascript node.js express sequelize.js

我正在创建一个用于存储用户会话的表。我将使用以下方法将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中无法正常运行。

3 个答案:

答案 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