2016-08-26 6 views
5

मेरे पास एक तालिका में यह सरल क्वेरी है जिसमें bigint प्रकार का कॉलम है।पीजी-वादा स्ट्रिंग्स के रूप में पूर्णांक देता है

हालांकि जब मैं इसे पूछता हूं, pg-promise इस कॉलम के मान को स्ट्रिंग के रूप में लौटाता है। मुझे दस्तावेज में इसके बारे में जानकारी नहीं मिल रही है। क्या वह मानक व्यवहार है?

[{id_brand: "180", brand: "Ford"}, {id_brand: "120", brand: "Nike"}] 

वहाँ pg-promise निर्देश देने के लिए वास्तविक प्रकार वापस जाने के लिए कुछ भी है:

var ids = [180, 120]; 

db.any('SELECT id_brand, brand from catalog_brand WHERE id_brand in ($1:csv)', [ids]) 
    .then((data) => { 
     // return results 
    }); 

data स्ट्रिंग पूर्णांक के बजाय के रूप में आईडी के साथ निम्नलिखित रूप लेता है,?

उत्तर

11

यह वास्तव में मानक व्यवहार है।

bigint 64-बिट है, और सभी 64-बिट पूर्णांकों, प्रकार string के रूप में अंतर्निहित node-postgres चालक द्वारा दिया जाता है, जबकि 32-बिट वाले number रूप में वापस आ रहे हैं।

इसका कारण यह है कि 64-बिट पूर्णांक में जावास्क्रिप्ट में सटीक मूल प्रस्तुति नहीं होती है, जो केवल कुछ सटीक सटीकता के साथ 64-बिट संख्याएं प्रस्तुत कर सकती है, और यह 64- बिट संख्याएं

यह भी देखें: How to do 64bit Integer arithmetic in Node.js?


इस समस्या के तीन संभावित हल ...

समाधान 1

स्टोर करने के लिए 64-बिट पूर्णांकों का उपयोग न करें ईद-एस रहे हैं , यदि आपकी तालिका में 4 बिलियन से अधिक रिकॉर्ड होने की उम्मीद नहीं है, तो इसके बजाय डिफ़ॉल्ट int प्रकार का उपयोग करें, जो 32-बिट है, और स्वचालित रूप से पूर्णांक के रूप में वापस कर दिया जाएगा।

समाधान 2

ऑन-द-मक्खी पूर्णांकों में कन्वर्ट लौटे आईडी-, लेकिन मन में है कि एक बार अपने आईडी-पहुँच संख्या काफी अधिक (53 बिट), परिवर्तित मूल्यों बन जाएगा रखना विकृत/बदला गया।

हालांकि, आप एक विशेष लाइब्रेरी का उपयोग कर सकते हैं जो एक स्ट्रिंग को 64-बिट पूर्णांक में परिवर्तित कर सकता है (उपरोक्त लिंक देखें), लेकिन यह प्रश्नों के उपयोग के लिए अजीब हो सकता है।


ऑन-द-मक्खी अपने आईडी-एस में परिवर्तित करने का उदाहरण:

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 
    }); 

Database.each देखें।

एक और उदाहरण के रूप में, रिकॉर्ड मायने रखता है हमेशा bigint रूप में वापस आ रहे हैं, इसलिए सबसे अच्छा तरीका है उन पाने के लिए इस तरह, इन-लाइन मूल्य परिवर्तन + रूपांतरण के माध्यम से है:

db.one('SELECT count(*) FROM catalog_brand', [], c => +c.count) 
    .then(count => { 
     // count = a proper integer value, rather than an object with a string 
    }); 

Database.one देखें।

समाधान 3

आप अंतर्निहित node-postgres चालक उपेक्षा रूपांतरण सुरक्षा बनाने के लिए और हर जगह पूर्णांकों में इस तरह के प्रकार बदल सकते हैं। मैं नहीं कह सकता है अगर यह सामान्य रूप में एक अच्छा विचार है, केवल यह है कि यह आसानी से किया जा सकता है, pgp.pg.types.setTypeParser(...) के माध्यम से (pg-types देखें):

// Convert bigserial + bigint (both with typeId = 20) to integer: 
pgp.pg.types.setTypeParser(20, parseInt); 

ध्यान दें कि समाधान 2 और 3 एक ही बात करते हैं, लेकिन दो विभिन्न स्तरों पर:

  • समाधान में स्पष्ट स्थानीय रूपांतरण 2
  • समाधान में निहित वैश्विक रूपांतरण 3
संबंधित मुद्दे