19

I using nodejs v4 with sequelize, and I have a model like this:

var Device = sequelize.define('Device', {
id: {
  type: DataTypes.BIGINT,
  primaryKey: true,
  autoIncrement: true
},
tenantId: {
  type: DataTypes.BIGINT,
  allowNull: false
},
token: {
  type: DataTypes.STRING,
  allowNull: false
}
}, {
 tableName: 'devices'
});

When I select a device by id the type of id is a string, exemple:

Device.findById(9).then( function(result) {
  console.log(result.toJSON().id + 10);
});

The output will be 910, rather than 19, so I look at json and a saw this:

{
  id: "9"
  tenantId: "123"
  token: "adsadsdsa"
}

The id in found device is a string, but I defined it as a number...

Doesn't it should be { "id": 9 } ?

How can I select a device with the types that I defined previously?

5 Answers 5

12

BIGINT maximum value is 2^63-1, javascript can safely represent up to 2^53. To be on the safe side libraries return those numbers as strings.

If you want to have numbers instead of strings, you can use this library https://github.com/mirek/node-pg-safe-numbers which deals with this issue.

Sign up to request clarification or add additional context in comments.

Comments

10

I found a fix to this problem on sequelize repo.

https://github.com/sequelize/sequelize/issues/4523

The pg module used for sequelize returns bigint as string because bigints are not guaranteed to fit into js numbers. So I change my model to use integer (DataTypes.INTEGER)

1 Comment

Correct me if I am wrong but I think you would have to change your DB schema as well for this to work. In my example (postgres) it doesn't fix anything.
2

IMO, a smoother solution is to force parsing of int to int, instead of strings. Checkout this issue and comments.

1 Comment

but what will be the result if the int from the string is larger then the biggest safe int in JS?)
1

Trying to put this line before your logic code worked for me, this forces parsing of int8 to int, instead of strings:

require("pg").defaults.parseInt8 = true;

...

try {
    const list = await Posts.findAll();
    console.log(JSON.stringify(list));
} catch (e) {
    console.log(e.message);
}

2 Comments

This works for my use case, but worth noting that if you have numbers larger than 2^53 then it may return incorrect values.
Sorry, I made an edit request to your answer by mistake.
0

What I did on my sequelize model was to apply parseFloat in the getter function

Here is a sample typescript code

@Column({
    type: DataType.DECIMAL(9, 2),
    get() {
        return parseFloat(this.getDataValue('amount') as string);
    },
})
amount?: number;

With this, you can apply your logic to deal with small and big int datatypes

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.