PostgreSQL Numeric DataType geeft mij een String terug

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • argon007
  • Registratie: April 2011
  • Laatst online: 16:02
Hallo,

Ik ben geen programmeur en dus gewoon hobbymatig wat bezig met NodeJS en Postgres. Ik heb 3 kolommen aangemaakt in een tabel met als DataType "Numeric". De waarden van de 3 kolommen worden opgevuld door NodeJS ism het PG package.

Bij het aanmaken van het "Numeric" DataType heb ik geen "precision" of "scale" meegegeven omdat de exacte waarden op voorhand niet gekend zijn. De waarden zijn wel altijd positief en groter dan 0.

De Precision kan (hoeft niet altijd) 15 zijn
De Scale kan (hoeft niet altijd) 8 zijn

Als ik via NodeJS de gegevens van een rij ophaal dan krijg ik voor de 3 waarden altijd een String terug ipv een nummer/decimaal.

Welk Datatype en welke settings moet ik gebruiken zodat Postgres volgende waarden effectief saved als Numeriek/Decimaal en niet als String:
123456789101115
123
0.12345678
100.12345678

Dit is het stukje code die ik gebruik (random voorbeeld):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
async function test() {
    //Insert
    let insertquery = 'INSERT INTO table(name, gender, age, length, calculation) VALUES ($1, $2, $3, $4, $5)';
    let values = ["JAN", "MALE", 50, 180, 0.12345678]
    let insert = await execute(insertquery, values)

    //Select
    let query = "SELECT * from table"
    let select = await execute(query)
    console.log(select.rows[0])
    var test = select.rows[0].gender + 100
    console.log(test)
}


En dit is dan het resultaat die ik krijg in Nodejs:
code:
1
2
3
4
5
6
7
8
9
{
  id: 26,
  name: 'JAN',
  gender: 'MALE',
  age: '50',
  length: '180',
  calculation: '0.12345678'
}
50100


Zoals je ziet staat zowel "Age", "Length" als "Calculation tussen quotes en krijg ik het dus terug als "String" en niet als een numerieke/decimale waarden.

Wie geeft mij een duwtje in de goeie richting? :-)

Bedankt!

Relevante software en hardware die ik gebruik
NodeJS
NPM package PG
pgAdmin

Beste antwoord (via argon007 op 07-12-2022 14:40)


  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 17:34
Hoe het moet werken: Gebaseerd op het datatype in PostgreSQL zal dat NPM package moeten zorgen voor een correcte mapping naar javascript types. Hier staat dat het zou moeten werken:
node-postgres will convert a database type to a JavaScript string if it doesn't have a registered type parser for the database type.
Dus er kunnen verschillende dingen mis zijn:
- Je data type in de tabel is NIET Numeric. Kun je eens een CREATE TABLE laten zien van die tabel?
- (vergezocht) elk data type in postgresql heeft een ID. node-postgres gebruikt die ID om de conversie te doen van Postgresql naar javascript. De ID voor Numeric moet 1700 zijn. Wat krijg je als je deze query runt in pg admin:
code:
1
select typname, oid, typarray from pg_type where typname = 'numeric'

- De types conversie wordt niet geladen. misschien moet je ergens eerst
code:
1
var types = require('pg').types
(maar dit lijkt me sterk)

Alle reacties


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 17:34
Hoe het moet werken: Gebaseerd op het datatype in PostgreSQL zal dat NPM package moeten zorgen voor een correcte mapping naar javascript types. Hier staat dat het zou moeten werken:
node-postgres will convert a database type to a JavaScript string if it doesn't have a registered type parser for the database type.
Dus er kunnen verschillende dingen mis zijn:
- Je data type in de tabel is NIET Numeric. Kun je eens een CREATE TABLE laten zien van die tabel?
- (vergezocht) elk data type in postgresql heeft een ID. node-postgres gebruikt die ID om de conversie te doen van Postgresql naar javascript. De ID voor Numeric moet 1700 zijn. Wat krijg je als je deze query runt in pg admin:
code:
1
select typname, oid, typarray from pg_type where typname = 'numeric'

- De types conversie wordt niet geladen. misschien moet je ergens eerst
code:
1
var types = require('pg').types
(maar dit lijkt me sterk)

Acties:
  • 0 Henk 'm!

  • argon007
  • Registratie: April 2011
  • Laatst online: 16:02
Dag Kalentum

code:
1
2
3
4
5
6
7
8
CREATE TABLE table (
    id serial NOT NULL PRIMARY KEY,
    name character varying NOT NULL,
    gender character varying NOT NULL,
    age numeric,
    length numeric,
    calculation numeric
);


Bij het uitvoeren van die "select typname, oid, ..." krijg ik het volgende:
Afbeeldingslocatie: https://media.discordapp.net/attachments/654236086838755340/1049983460367933501/image.png

die var types = ... zal ik nog eens moeten opzoeken wat je hier net mee wil zeggen en hoe ik dit net in mijn code kan verwerken.

Groeten

//Edit:

Aha, op het eerste zicht lijkt dit geholpen te hebben. Nog even verder mee testen.

[ Voor 13% gewijzigd door argon007 op 07-12-2022 10:53 ]


Acties:
  • 0 Henk 'm!

  • Kalentum
  • Registratie: Juni 2004
  • Laatst online: 17:34
argon007 schreef op woensdag 7 december 2022 @ 10:41:
Dag Kalentum

code:
1
2
3
4
5
6
7
8
CREATE TABLE table (
    id serial NOT NULL PRIMARY KEY,
    name character varying NOT NULL,
    gender character varying NOT NULL,
    age numeric,
    length numeric,
    calculation numeric
);


Bij het uitvoeren van die "select typname, oid, ..." krijg ik het volgende:
[Afbeelding]

die var types = ... zal ik nog eens moeten opzoeken wat je hier net mee wil zeggen en hoe ik dit net in mijn code kan verwerken.

Groeten

//Edit:

Aha, op het eerste zicht lijkt dit geholpen te hebben. Nog even verder mee testen.
Nou, prima gevonden! Dus die conversie wordt niet automatisch gedaan. Misschien komt dat omdat er mogelijk NUMERIC values in PG kunnen zijn die niet goed in javascript kunnen worden gebruikt. Nou ja dit zal wel werken dan.

Acties:
  • 0 Henk 'm!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 16:13

Knutselsmurf

LED's make things better

Als ik even snel de documentatie bekijk van het Numeric-datatype, dan is het logsich dat dit naar een string wordt omgezet in javascript. Er is namelijk geen overeenkomstig datatype in javascript. Door je data in javascript om te zetten naar een float, volgens het linkje in je laatste post, verlies je namelijk (mogelijk) precisie.

In plaats van 'numeric' kun je beter een datatype gebruiken dat beter aansluit bij het veld, iets minder generiek dus.

En hoewel het wellicht een voorbeeld is, zou ik dus zelf nooit van iemand de leeftijd opslaan in de database, maar de geboortedatum. De geboortedatum verandert namelijk niet en de leeftijd is hier slechts een afgeleide van, die van dag tot dag verandert.

- This line is intentionally left blank -


Acties:
  • 0 Henk 'm!

  • doskabouter
  • Registratie: Oktober 2004
  • Laatst online: 17:08
Helemaal mee eens.

Voor de voorbeelden hier aangegeven is numeric behoorlijk overkill.
Behalve dat dus sommige libraries dit niet naar een native (javascrpt) type kunnen converteren is het werken met numerics (zeker in berekeningen in postgres) een paar ordes van grootte trager dan de simpelere float/double/integers

Het grote voordeel van windows is dat je meer dos-boxen kan openen


Acties:
  • 0 Henk 'm!

  • argon007
  • Registratie: April 2011
  • Laatst online: 16:02
Maar wat neem je dan best wanneer je niet weet of er een geheel getal in komt te staan of een Decimaal getal (en je ook de lengte niet weet)?

Acties:
  • 0 Henk 'm!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 16:13

Knutselsmurf

LED's make things better

argon007 schreef op woensdag 7 december 2022 @ 21:47:
Maar wat neem je dan best wanneer je niet weet of er een geheel getal in komt te staan of een Decimaal getal (en je ook de lengte niet weet)?
Heel bot gezegd moet je dan je datamodel opnieuw bekijken :) Als je niet weet wat voor data er in dat veld komt te staan, hoe weet je dan wat er er mee moet doen? Als je datamodel goed in elkaar zit, weet je welke gegevens in welke veld staan, en dus wat voor datatype daar het beste bij past. Je weet blijkbaar wel dat het ergens een getal moet zijn, maar blijkbaar niet wat dit getal voor moet stellen. Een aantal kippen, een geldbedrag, een lengte? Dat is toch wel handig als je met deze gegevens iets gaat doen.

- This line is intentionally left blank -


Acties:
  • 0 Henk 'm!

  • argon007
  • Registratie: April 2011
  • Laatst online: 16:02
Het gaat hem hier specifiek over Crypto traden op Binance.

In een kolom hou ik het OrderId bij. Het orderID is altijd een rond getal maar heeft geen vast aantal nummers, dit hangt namelijk af van de Cryptomunt waarin je een order plaatst. Dus de ene keer kan dit 7 cijfers bevatten, de andere keer 15 (ik zeg maar iets).

In een andere kolom hou ik de prijs waar ik mijn verkooporder heb gezet. Wederom kan dit verschillen per munt, maar meestal is dit wel een Decimaal getal. Maar de ene keer gaat dit over 2 cijfers na de komma, een andere keer over maximum 8 cijfers na de komma.

Acties:
  • +1 Henk 'm!

  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 16:13

Knutselsmurf

LED's make things better

argon007 schreef op woensdag 7 december 2022 @ 22:00:
Het gaat hem hier specifiek over Crypto traden op Binance.

In een kolom hou ik het OrderId bij. Het orderID is altijd een rond getal maar heeft geen vast aantal nummers, dit hangt namelijk af van de Cryptomunt waarin je een order plaatst. Dus de ene keer kan dit 7 cijfers bevatten, de andere keer 15 (ik zeg maar iets).

In een andere kolom hou ik de prijs waar ik mijn verkooporder heb gezet. Wederom kan dit verschillen per munt, maar meestal is dit wel een Decimaal getal. Maar de ene keer gaat dit over 2 cijfers na de komma, een andere keer over maximum 8 cijfers na de komma.
Dan zou ik voor het ID geel numeric datatype gebruiken, maar gewoon een varchar. Het is geen getal waarmee je gaat rekenen, en waarbij bijvoorbeeld voorloopnullen relevant kunnen zijn.

Voor de prijs is het een iets ander verhaal. Voor bedragen wil je in principe een decimal met een vaste precisie. Nadeel hiervan is, dat hier in javascript ook geen correct datatype voor beschikbaar is. Is de precisie een eigenschap van de verhandelde cryptomunt, of kan dit per transactie verschillen?

Als iedere cryptomunt zijn eigen precisie heeft, zou je bijvoorbeeld als eigenschap van de munt deze precisie op kunnen slaan, en vervolgens de prijzen als een integer opslaan. Bijvoorbeeld een transactie in Bitcoin is altijd in 6 decimalen. Een prijs van 0,020000 BTC slaan je dan op als 20000. Omdat het niet logisch is om in de database 0,020000 BTC en 0,100 ETH bij elkaar op te tellen, is het niet erg dat ze op een andere wijze worden opgeslagen.

Als laatste is nog van belang wat je met deze gegevens gaat doen. Als je ze alleen wilt tonen, kun je bij wijze van spreken alles als varchar opslaan :)

- This line is intentionally left blank -

Pagina: 1