2014-05-21 6 views
5

मेरे पास कई टेबल के साथ एक पोस्टग्रेज़ डेटाबेस है जिसे मैं अपडेट के लिए देखना चाहता हूं, और यदि कोई अपडेट है, तो मैं "हे, कुछ बदल गया" अपडेट आग लगाना चाहता हूं। यह मूल मामले में काम करता है, लेकिन अब चीजों को बेहतर बनाने का समय है।पोस्टग्रेस अपडेट ट्रिगर में कॉलम परिवर्तनों का पता लगाना

CREATE FUNCTION notify_update() RETURNS trigger AS $notifyfunction$ 
BEGIN 
    PERFORM pg_notify('update_watchers', 
    $${"event":"update", "type": "$$ || TG_TABLE_NAME || $$", "payload": {"id": $$ || new.id || $$}}$$); 
    RETURN new; 
END; 
$notifyfunction$ LANGUAGE plpgsql; 

ठीक काम करता है। मैं तो जैसे तालिका में अटैच कर:

CREATE TRIGGER document_update_body 
AFTER UPDATE ON documents 
FOR EACH ROW EXECUTE PROCEDURE notify_update(); 

(एक पक्ष सवाल के रूप में: वहाँ किसी भी बेहतर/आसान mess'o '$$ ट्रिगर समारोह की तुलना में मेरी ट्रिगर परिणाम JSON.stringify लिए तरीका है, कृपया मुझे बताएं। उद्धरण उद्धरण चिह्न संतुलित करना मजेदार नहीं है)।

मैं जो करना चाहता हूं वह है pg_notify कॉल को बदलने वाले कॉलम की एक सूची को कॉल करें। यह प्रतीत होता है जैसे तालिका में कॉलम पर पुनरावृत्ति करने के अलावा ऐसा करने का कोई आसान तरीका है और यह जांचना कि NEW.col OLD.col से अलग है या नहीं। ऐसा करने का बुरा तरीका मेरी अधिसूचना प्रक्रिया में स्तंभ नामों को हार्ड-कोड करना होगा (नाजुक, अगर मैं अपनी स्कीमा बदलता हूं, तो अपडेट करने के लिए एक और चीज)।

मैं plpgsql लिखने पर भी अपनी गहराई से बाहर हूं, वास्तव में, इसलिए मुझे यकीन नहीं है कि सहायता कहां देखना है। आदर्श रूप से, (यदि कोई अपडेट_columns ब्लॉक वैरिएबल नहीं है जिसे मैंने प्रलेखन में नहीं देखा था) तो प्रदर्शन ओवरहेड के बहुत गंभीर होने के बिना अधिसूचना ब्लॉक के अंदर तालिका की स्कीमा प्राप्त करने का एक तरीका होगा (क्योंकि इन तालिकाओं को अपडेट किया जाएगा निष्पक्ष बिट)।

उत्तर

6

hstore एक्सटेंशन पर पढ़ें। विशेष रूप से आप एक पंक्ति, आप की तरह कुछ कर सकते हैं, जिसका मतलब है से एक hstore बना सकते हैं: थोड़ा और अधिक जानकारी की तुलना में आप चाहता था कि

changes := hstore(NEW) - hstore(OLD); 
...pg_notify(... changes::text ...) 

(नए मूल्यों भी शामिल है)। यदि आप केवल चाबियाँ चाहते हैं तो आप akeys(changed) का उपयोग कर सकते हैं।

+0

यह एकदम सही था - मैंने किया pg_notify ... hstore_to_json (hstore (नया) - hstore (पुराना)) ..., जो सरणी प्रकार कॉलम में महान के सिवा परिवर्तन काम करता है (वे में munged हो स्ट्रिंग्स जो वास्तविक "वैल" के बजाय पोस्टग्रेस सरणी "{1, 2, 3}" की तरह दिखती हैं: परिणामस्वरूप जेसन में [1, 2, 3] लोग, लेकिन मैं क्लाइंट पक्ष पर इसका सामना कर सकता हूं क्योंकि यह एक पार्सिंग है मुद्दा – pfooti

+0

9.3 में जेसन प्रकार है और 9.4 में आने वाले कई सुधार (अब बीटा) आ रहे हैं। –

0

http://www.postgresql.org/docs/9.3/static/plpython-trigger.html

TD["table_name"] 

मैं बिल्कुल सूचित के एक ही प्रकार करते हैं, मैं इस तरह के सभी कॉलम के माध्यम से लूप:

for k in TD["new"]: 
     if TD["old"][k] != TD["new"][k]: 
      changed.append(k) 

changed.append (के) मेरी सूचना स्ट्रिंग बनाता है। कहीं और मैं एक सुनता हूं, फिर परिणामों को पब/उप से वेब सॉकेट क्लाइंट में प्रसारित करता हूं।

जी

संबंधित मुद्दे