最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Node.js Sequelize gettersetter RangeError - Stack Overflow

programmeradmin1浏览0评论

I'm creating a table to store user sessions in. I'm going to store the IP address as an integer, using these methods: IP-addresses stored as int results in overflow?

I would like to specify a getter and setter for the IP field so that it may automatically convert between an IP and int.

Unfortunately I get the following error and I have no idea what's happening. I've been trying to fix it for hours and Google yields me no results:

RangeError: Maximum call stack size exceeded

Model:

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;
        }
    }
});

Inserting an 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"
})

I can confirm that the getter/setter code does convert as desired, but it is not functioning in Sequelize properly.

I'm creating a table to store user sessions in. I'm going to store the IP address as an integer, using these methods: IP-addresses stored as int results in overflow?

I would like to specify a getter and setter for the IP field so that it may automatically convert between an IP and int.

Unfortunately I get the following error and I have no idea what's happening. I've been trying to fix it for hours and Google yields me no results:

RangeError: Maximum call stack size exceeded

Model:

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;
        }
    }
});

Inserting an 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"
})

I can confirm that the getter/setter code does convert as desired, but it is not functioning in Sequelize properly.

Share Improve this question edited May 23, 2017 at 11:45 CommunityBot 11 silver badge asked Aug 5, 2013 at 0:52 Jacob BrunsonJacob Brunson 1,4924 gold badges24 silver badges37 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

I too ran into this problem with Sequelize. I was reading and re-reading the official documentation, searching everywhere I knew to search on the internet, and I finally wound up here. Once I found your question, with no answers, I decided to search the source code of Sequelize itself. Sure enough, I found the answer!

If you look at the file sequelize/test/dao-factory.test.js in Sequelize's source code, you'll discover the following bit of code lurking inside a test case:

setterMethods: {
  price1: function(v) { this.setDataValue('price1', v * 100) }
},

I copied the syntax above, used it in my own setter method, and it works!

They really should update the documentation on the sequelize website.. Hmm.. Perhaps I should look into helping them out with that? Any way, best of luck to you!

I don't know if someone is still running this error, but if you are having troubles with this here is how I've solved the issue.

I had a similar situation where I had a UserModel object which was looking like this:

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"
    }
}

And my setters and getters were:

{
    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);
        }
    }
});

And of course I had the stack error.

To solve this, I've just changed my setters and getters to this:

 {
    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);
        }
    }
});

And everything went magically well, despite in many examples online I've seen people suggesting the approach of providing the same setters / getters name as the fields.

So, in a nutshell, changing to setters and getters name so that their name won't match any of the defined fields solved my issue. Good practice? I'm not sure, but it solved my problem.

I had a similar situation and I resolve in this way

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;

When I call this.davaValues.column_name it not call recoursive getterMethod for that column

发布评论

评论列表(0)

  1. 暂无评论