Jest to rzeczywiście standardowe zachowanie.
bigint
jest 64-bitowy, a wszystkie 64-bitowe liczby całkowite są zwracane przez leżącej node-postgres kierowcy jako typ string
, natomiast te, 32-bitowe są zwracane jako number
.
Powodem tego jest to, że 64-bitowa liczba całkowita nie ma dokładnej natywnej prezentacji w JavaScript, która może prezentować tylko 64-bitowe liczby z pewną precyzją, i która nie jest odpowiednia do reprezentowania pełnego zakresu 64- liczby bitowe.
Zobacz także: How to do 64bit Integer arithmetic in Node.js?
Istnieją trzy możliwe rozwiązania tego problemu ...
Rozwiązanie 1
Nie używać 64-bitowe liczby całkowite przechowywanie ID-s , jeśli twoja tabela nie ma nigdy więcej niż 4 miliardy rekordów, użyj domyślnie typu int
, który jest 32-bitowy i zostanie automatycznie zwrócony jako liczba całkowita.
Rozwiązanie 2
Konwersja zwrócony id-s do liczb całkowitych on-the-fly, ale należy pamiętać, że kiedyś swój identyfikator-s numery zasięgu wystarczająco wysokie (53 bitów), wartości skonwertowane staną zniekształcony/zmieniony.
Można jednak użyć wyspecjalizowanej biblioteki, która może poprawnie przekonwertować ciąg na 64-bitową liczbę całkowitą (zobacz powyższy link), ale korzystanie z zapytań może być niewygodne.
Przykład konwersja id-s on-the-fly:
db.each('SELECT id_brand FROM catalog_brand WHERE id_brand in ($1:csv)', [ids], cat=> {
cat.id_brand = parseInt(cat.id_brand)
})
.then(rows => {
// id_brand is now an integer in each row
});
Zobacz Database.each.
Jako inny przykład, liczy rekord są zawsze zwracane jako bigint
, więc najlepszym sposobem na uzyskanie tych jest poprzez transformację w linii wartości + nawrócenia, tak:
db.one('SELECT count(*) FROM catalog_brand', [], c => +c.count)
.then(count => {
// count = a proper integer value, rather than an object with a string
});
Zobacz Database.one.
Rozwiązanie 3
Można dokonać bazowego lekceważenie node-postgres Kierowca bezpieczeństwo konwersji i konwertować do takich rodzajów liczb wszędzie. Nie mogę powiedzieć, czy jest to dobry pomysł w ogóle, tylko, że można to zrobić łatwo, poprzez pgp.pg.types.setTypeParser(...)
(patrz pg-types):
// Convert bigserial + bigint (both with typeId = 20) to integer:
pgp.pg.types.setTypeParser(20, parseInt);
Należy zauważyć, że rozwiązania 2 i 3 zrobić to samo, ale na dwóch różnych poziomach:
- wyraźnej lokalnej konwersji w roztworze 2
- niejawna konwersja globalny w roztworze 3