Knex: Le type 'bigint' est une chaîne dans les résultats de la requête.

Créé le 21 juil. 2014  ·  6Commentaires  ·  Source: knex/knex

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' } ]
PostgreSQL question

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')

var pg = require('pg')
pg.types.setTypeParser(20, 'text', parseInt)

Tous les 6 commentaires

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?

  1. JS: query.where("bigintkey", "123456")
  2. si le "bigintkey" est de type bigint
  3. SQL: 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.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

mtom55 picture mtom55  ·  3Commentaires

lanceschi picture lanceschi  ·  3Commentaires

tjwebb picture tjwebb  ·  3Commentaires

marianomerlo picture marianomerlo  ·  3Commentaires

arconus picture arconus  ·  3Commentaires