PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

मैं ActiveRecord का उपयोग करके Postgres कॉलम डिफ़ॉल्ट मान तक कैसे पहुँच सकता हूँ?

जब ActiveRecord को किसी तालिका के बारे में जानने की आवश्यकता होती है तो यह आपके information_schema जैसी क्वेरी करता है क्वेरी लेकिन एआर पोस्टग्रेएसक्यूएल-विशिष्ट सिस्टम टेबल इसके बजाय:

  SELECT a.attname, format_type(a.atttypid, a.atttypmod),
         pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
    FROM pg_attribute a LEFT JOIN pg_attrdef d
      ON a.attrelid = d.adrelid AND a.attnum = d.adnum
   WHERE a.attrelid = '#{quote_table_name(table_name)}'::regclass
     AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum

PostgreSQL अडैप्टर स्रोत खोजें "regclass" के लिए और आप कुछ अन्य प्रश्न देखेंगे जिनका उपयोग AR तालिका की संरचना का पता लगाने के लिए करेगा।

pg_get_expr कोड> उपरोक्त क्वेरी में कॉल वह जगह है जहां से कॉलम का डिफ़ॉल्ट मान आता है।

उस क्वेरी के परिणाम, कमोबेश, सीधे PostgreSQLColumn.new में :

def columns(table_name, name = nil)
  # Limit, precision, and scale are all handled by the superclass.
  column_definitions(table_name).collect do |column_name, type, default, notnull|
    PostgreSQLColumn.new(column_name, default, type, notnull == 'f')
  end
end

PostgreSQLColumn कंस्ट्रक्टर extract_value_from_default रूबी के लिए- डिफ़ॉल्ट रूप से ify; का अंत switch में extract_value_from_default यहाँ दिलचस्प है:

else
  # Anything else is blank, some user type, or some function
  # and we can't know the value of that, so return nil.
  nil

इसलिए यदि डिफ़ॉल्ट मान एक अनुक्रम के लिए बाध्य है (जो एक id . है पोस्टग्रेएसक्यूएल में कॉलम होगा), फिर डिफ़ॉल्ट डेटाबेस से इस तरह के फ़ंक्शन कॉल के रूप में बाहर आ जाएगा:

nextval('models_id_seq'::regclass)

वह ऊपर else में समाप्त होगा शाखा और column.default.nil? सच होगा।

id . के लिए कॉलम यह कोई समस्या नहीं है, एआर डेटाबेस से id . के लिए मूल्यों की आपूर्ति की अपेक्षा करता है कॉलम इसलिए यह परवाह नहीं करता कि डिफ़ॉल्ट मान क्या है।

यह एक बड़ी समस्या है यदि कॉलम का डिफ़ॉल्ट कुछ ऐसा है जिसे AR समझ नहीं पाता है, ऐसे फ़ंक्शन कॉल कहें md5(random()::text) . के रूप में . समस्या यह है कि एआर सभी विशेषताओं को उनके डिफ़ॉल्ट मानों के लिए प्रारंभ करेगा - जैसे कि Model.columns उन्हें देखता है, जैसा कि डेटाबेस उन्हें देखता है - जब आप कहते हैं Model.new . उदाहरण के लिए, कंसोल में आप इस तरह की चीज़ें देखेंगे:

 > Model.new
=> #<Model id: nil, def_is_function: nil, def_is_zero: 0>

तो अगर def_is_function वास्तव में फ़ंक्शन कॉल को इसके डिफ़ॉल्ट मान के रूप में उपयोग करता है, एआर इसे अनदेखा कर देगा और उस कॉलम के मान के रूप में एक न्यूल डालने का प्रयास करेगा। वह NULL डिफ़ॉल्ट मान का उपयोग होने से रोकेगा और आप एक भ्रमित करने वाली गड़बड़ी के साथ समाप्त हो जाएंगे। डिफ़ॉल्ट जिन्हें एआर समझ सकता है (जैसे स्ट्रिंग्स और नंबर) हालांकि ठीक काम करते हैं।

नतीजा यह है कि आप वास्तव में ActiveRecord के साथ गैर-तुच्छ डिफ़ॉल्ट कॉलम मानों का उपयोग नहीं कर सकते हैं, यदि आप एक गैर-तुच्छ मान चाहते हैं तो आपको रूबी में ActiveRecord कॉलबैक में से एक के माध्यम से करना होगा (जैसे before_create )।

आईएमओ यह बहुत बेहतर होगा यदि एआर ने डिफ़ॉल्ट मानों को डेटाबेस तक छोड़ दिया अगर यह उन्हें समझ में नहीं आया:उन्हें INSERT से बाहर छोड़कर या VALUES में DEFAULT का उपयोग करने से बेहतर परिणाम मिलेंगे; एआर, निश्चित रूप से, सभी उचित डिफ़ॉल्ट प्राप्त करने के लिए डेटाबेस से नई बनाई गई वस्तुओं को फिर से लोड करना होगा, लेकिन अगर एआर को समझ में नहीं आया तो आपको केवल फिर से लोड करने की आवश्यकता होगी। अगर else में extract_value_from_default nil . के बजाय एक विशेष "मैं नहीं जानता इसका क्या अर्थ है" ध्वज का उपयोग किया तो "मुझे पहली बार सहेजने के बाद इस ऑब्जेक्ट को फिर से लोड करने की आवश्यकता है" स्थिति का पता लगाने के लिए तुच्छ होगा और आप केवल आवश्यक होने पर ही पुनः लोड करेंगे।

उपरोक्त PostgreSQL-विशिष्ट है लेकिन प्रक्रिया अन्य डेटाबेस के लिए समान होनी चाहिए; हालांकि, मैं कोई गारंटी नहीं देता।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. स्तंभ मान अपडेट करें PostgreSQL

  2. libpq . का उपयोग करके तालिका में फ़्लोटिंग पॉइंट नंबर डालना

  3. सभी प्रक्रियात्मक, उपयोगकर्ता परिभाषित कार्य प्राप्त करें

  4. सेल.जेएस संबंधों द्वारा ब्लूप्रिंट क्वेरी

  5. ActiveRecord ::StatementInvalid:PG ::त्रुटि:त्रुटि:हरोकू में केवल-पढ़ने के लिए लेनदेन त्रुटि में अद्यतन निष्पादित नहीं कर सकता