La requête suivante renvoie un Postgres bigint
pour la colonne assigned_client_count
(résultats de COUNT(*)
.
Il s'agit d'une chaîne, plutôt que d'un Number
, dans les résultats renvoyés.
{ __cid: '__cid40',
method: 'select',
options: undefined,
bindings: [ 1 ],
sql: 'select "id", "name", "fluid_account_id", "survey_fid", coalesce(assigned_client_count, 0) as assigned_client_count from (select "survey_id", count(*) as "assigned_client_count" from "client_surveys" group by "survey_id") as "t_counts" right join "fluid_surveys" on "t_counts"."survey_id" = "fluid_surveys"."id" where "fluid_account_id" = $1' }
[ { id: 6,
name: 'some name',
fluid_account_id: 1,
survey_fid: 69942,
assigned_client_count: '1' } ]
Il s'agit donc d'une décision de conception node-postgres et pas vraiment de celle que nous pouvons abstraire non plus:
https://github.com/brianc/node-postgres/pull/353
node-postgres expose son analyseur de type afin que vous puissiez toujours remplacer sa valeur par défaut pour bigint et l'exécuter contre parseInt
pour toutes les requêtes.
Le problème ici est que si vous aviez de gros entiers, JS ne peut pas les traiter nativement. La valeur par défaut permet une précision totale et vous avez la possibilité de vous désinscrire si vous n'en avez pas besoin.
@ rhys-vdw http://mathjs.org/ est une bibliothèque qui peut gérer les bignumbers, et il y en a bien d'autres.
Acclamations gars. En fait, dans ce cas, il ne retournera que zéro ou un, donc je vais probablement examiner l'option de type parser.
@ rhys-vdw, j'ai le même problème. La solution consiste à ajouter les 2 lignes suivantes au-dessus de require('knex')
var pg = require('pg')
pg.types.setTypeParser(20, 'text', parseInt)
Bonjour gars. J'ai le même problème. Nous utilisons des bigints pour certaines tables éventuellement volumineuses.
Malheureusement, je considère la solution @sidazhang comme une dégradation du bigint en int (perte de précision éventuelle).
Proposez-vous plutôt de ne pas utiliser bigint ou il existe une solution de contournement qui garde la précision?
L'une d'elles qui m'est venue à l'esprit est d'accepter la chaîne comme représentation bigint, mais knex rejettera une telle requête dans une table avec des bigints conditionnés avec une chaîne comme valeur. En cas d'index, je n'ai pas besoin de faire d'opérations mathématiques sur le nombre.
Error: invalid input syntax for integer: "{"1"}"
at Connection.Object.<anonymous>.Connection.parseE (D:\repos\ImgPoolWebApp\node_modules\pg\lib\connection.js:553:11)
at Connection.Object.<anonymous>.Connection.parseMessage (D:\repos\ImgPoolWebApp\node_modules\pg\lib\connection.js:378:19)
at Socket.<anonymous> (D:\repos\ImgPoolWebApp\node_modules\pg\lib\connection.js:119:22)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at addChunk (_stream_readable.js:263:12)
at readableAddChunk (_stream_readable.js:250:11)
at Socket.Readable.push (_stream_readable.js:208:10)
at TCP.onread (net.js:597:20), level=error
Serait-il possible d'une manière ou d'une autre d'accepter la condition where avec string au cas où l'opérande de gauche serait bigint?
query.where("bigintkey", "123456")
WHERE "bigintkey" = 123456
La validité de la valeur devrait être gérée par les consommateurs.
Pour le moment, nous devons accepter les requêtes retournant la chaîne et les convertir en nombre dans des conditions => précision perdue.
Cela me semble être un problème d'API, quelle que soit la bibliothèque sous-jacente présente des limitations au niveau du moteur.
La solution de dernier recours serait pour nous d'utiliser des chaînes comme alternative à bigint dans db et de générer des uuids de préférence aux clés primaires auto-incrémentées.
@miroslavvojtus J'ai un gestionnaire (pour les types pg) qui convertit les bigints en nombres javascript et jette une erreur si la valeur est trop grande pour que le nombre puisse être géré. Si vos valeurs sont inférieures à 53 bits, vous ne perdrez aucune précision.
Je ne vois pas quel est le problème que vous rencontrez là-bas. Si vous aimez utiliser les bigints avec une précision totale, vous pouvez les conserver sous forme de chaînes côté javascript.
Commentaire le plus utile
@ rhys-vdw, j'ai le même problème. La solution consiste à ajouter les 2 lignes suivantes au-dessus de
require('knex')