2011-05-09 10 views
21

में MySQLdb का उपयोग कर क्रोनिक स्टाइल परिणाम My Python प्रोग्राम एक MySQL डीबी में टेबल के सेट से पूछताछ करता है, 30 सेकंड के लिए सोता है, फिर उन्हें फिर से पूछताछ करता है। प्रश्नों की तालिका लगातार तीसरे पक्ष द्वारा अपडेट की जाती है, और (जाहिर है) मैं हर 30 सेकंड में नए नतीजे देखना चाहता हूं।पाइथन

मान लीजिए कि मेरी क्वेरी इस तरह दिखता है:

"select * from A where A.key > %d" % maxValueOfKeyFromLastQuery 

नियमित रूप से मुझे लगता है कि मेरा कार्यक्रम एक या दो पुनरावृत्तियों के बाद नए परिणाम पाने के बंद हो जाता है देखेंगे, भले ही नई पंक्तियाँ तालिकाओं में मौजूद हैं। मुझे पता है कि टेबल में नई पंक्तियां मौजूद हैं क्योंकि जब मैं इंटरैक्टिव mysql (यानी पायथन से नहीं) से समान क्वेरी जारी करता हूं तो मैं उन्हें देख सकता हूं।

मुझे पता चला कि समस्या प्रत्येक पाइथन में दूर हो जाती है यदि मैं प्रत्येक क्वेरी के बाद डेटाबेस से अपना कनेक्शन समाप्त करता हूं और फिर अगली क्वेरी के लिए एक नया स्थापित करता हूं।

मैंने सोचा कि शायद यह एक सर्वर-साइड संचय मुद्दे के रूप में यहाँ पर चर्चा हो सकती है: Explicit disable MySQL query cache in some parts of program

हालांकि:

  1. जब मैं इंटरैक्टिव mysql खोल जाँच, यह कहना है कि कैशिंग पर है। मैं स्पष्ट रूप से मेरे अजगर कार्यक्रम के भीतर से SET SESSION query_cache_type = OFF पर अमल करते हैं (तो अगर यह एक कैशिंग समस्या है, कैसे आ इंटरैक्टिव खोल इससे पीड़ित नहीं करता है?)

  2. , समस्या अभी भी होती है।

प्रत्येक क्वेरी के लिए एक नया डीबी कनेक्शन बनाना एकमात्र तरीका है जिससे मैं समस्या को दूर करने में सक्षम हूं।

मैं पाइथन से अपने प्रश्न कैसे प्राप्त कर सकता हूं ताकि नए नतीजे देख सकें जो मुझे पता है?

+1

आप उपयोग नहीं करना चाहिए प्रश्नों में '%' प्रारूप ऑपरेटर। सभी प्लेसहोल्डर्स के लिए '% s' का उपयोग करें (कोई फर्क नहीं पड़ता कि उनका प्रकार क्या है) और मूल्यों के साथ एक tuple/सूची पास करें ताकि उन्हें ठीक से sanitized किया जा सके। – ThiefMaster

+1

बस एक अनुमान: सुनिश्चित करें कि डीबी से पढ़े गए आपके प्रश्न लेनदेन द्वारा अन्य परिवर्तनों से अलग नहीं हैं। अर्थात। प्रत्येक पढ़ने से पहले एक नया लेनदेन बनाएँ। – jsw

+3

@ थिफमास्टर: '% d' वास्तव में प्रश्नों में ठीक है, क्योंकि यह प्रतिस्थापन को पूर्णांक होने के लिए मजबूर करता है, जिसे एसक्यूएल इंजेक्शन हमलों के लिए उपयोग नहीं किया जा सकता है। – Jonathan

उत्तर

21

This website और this website में एक ही समस्या पर जानकारी है। अपनी टेबल को अद्यतित रखने के लिए, आपको अपने लेनदेन करना होगा। ऐसा करने के लिए db.commit() का उपयोग करें।

जैसा कि नीचे दी गई पोस्ट द्वारा उल्लिखित है, आप ऑटो-प्रतिबद्ध करने के द्वारा इसकी आवश्यकता को हटा सकते हैं। यह db.autocommit(True)

चलाकर भी किया जा सकता है, इसके अलावा, इंटरैक्टिव शैल में स्वत: प्रतिबद्धता सक्षम है, इसलिए यह बताता है कि आपको समस्या क्यों नहीं थी।

+0

टिप के लिए धन्यवाद! यह वास्तव में समस्या थी। मैं ओरेकल के लिए भी प्रयोग किया जाता है, मुझे लगता है। :) – dg99

+2

मुझे इससे भी फायदा हुआ। लेकिन क्या आप यह समझाने की परवाह कर सकते हैं कि ऑटोोकॉमिट क्यों चयन कथन में मदद करता है? मेरा स्रोत (देव में) PHPMyAdmin है जो हमेशा अद्यतन परिणाम देता है। लेकिन मेरे पायथन प्रोग्राम ने ऑटोकॉमिट सक्षम करने तक नहीं किया। – aitchnyu

+3

मेरे पास @aitchnyu जैसा ही समस्या है, मेरी पायथन प्रक्रिया केवल 'चयन' करती है। मेरे पास लेखन करने की पूरी तरह से अन्य प्रक्रिया है, मैंने 'execute()' 'execute()' के बाद और 'fetchall()' से पहले और यह काम करता है। यह अच्छा है, लेकिन आप पढ़े गए वक्तव्य पर 'प्रतिबद्ध() 'क्यों करते हैं? – Landon

9

आप सक्षम कर सकते हैं MySQLdb में स्वचालित रूप से ऑटो के लिए प्रतिबद्ध! निम्न का प्रयास करें:

conn = MySQLdb.Connect("host", "user", "password") 
conn.autocommit(True) 

यह आपको वही व्यवहार देता है जिसका उपयोग आप इंटरैक्टिव शैल में करते हैं।

+0

भी, एक कीवर्ड पैरामीटर 'autocommit' –

9

आप अपने डेटाबेस का लेनदेन अलगाव स्तर देखना चाहते हैं। आपके द्वारा वर्णित व्यवहार वह है जो आप उम्मीद कर सकते हैं यदि यह दोहराने योग्य-पढ़ने के लिए सेट है। आप इसे रीड-कमेटेड में बदलना चाहते हैं।

के बाद से समस्या के मूल पोस्टर कहा गया है कि वह केवल डेटाबेस से क्वेरी है, यह एक के लिए प्रतिबद्ध है कि भुला दिया गया नहीं हो सकता। एक प्रतिबद्धता डालना एक कामकाज प्रतीत होता है हालांकि यह एक नया लेनदेन शुरू करने का कारण बनता है; और एक नया स्नैपशॉट स्थापित करने की आवश्यकता हो सकती है।फिर भी, प्रत्येक चयन से पहले एक प्रतिबद्धता डालने के लिए मुझे अच्छा प्रोग्रामिंग प्रथाओं की तरह नहीं लगता है।

कोई पाइथन कोड दिखाने के लिए नहीं है क्योंकि समाधान डेटाबेस को सही तरीके से कॉन्फ़िगर करने में निहित है।

http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html पर DO जांच MySQL प्रलेखन।

repeatable पढ़ें
यह InnoDB के लिए डिफ़ॉल्ट अलगाव स्तर है। लगातार पढ़ने के लिए, रीड कमेटेड अलगाव स्तर से एक महत्वपूर्ण अंतर है: एक ही लेन-देन के भीतर सभी लगातार पढ़े गए पहले पढ़ने द्वारा स्थापित स्नैपशॉट पढ़ें। इस सम्मेलन का अर्थ है कि यदि आप एक ही लेनदेन के भीतर कई सादे (नॉनलॉकिंग) चयन विवरण जारी करते हैं, तो ये चयन विवरण एक-दूसरे के संबंध में भी सुसंगत हैं। धारा 14.3.9.2, "निरंतर नॉनलाकिंग रीड" देखें।

पढ़ें कमिट
एक सुसंगत (nonlocking) के संबंध में कुछ हद तक ओरेकल की तरह अलगाव स्तर पर लिखा है: प्रत्येक लगातार पढ़ने, यहां तक ​​कि एक ही लेन-देन के भीतर, सेट और अपने स्वयं के ताजा स्नैपशॉट पढ़ता है। धारा 14.3.9.2, "निरंतर नॉनलाकिंग रीड" देखें।

कॉन्फ़िगर किया गया अलगाव स्तर जाँच हो रही है:

>mysql > SELECT @@GLOBAL.tx_isolation, @@tx_isolation; 
+-----------------------+-----------------+ 
| @@GLOBAL.tx_isolation | @@tx_isolation | 
+-----------------------+-----------------+ 
| REPEATABLE-READ  | REPEATABLE-READ | 
+-----------------------+-----------------+ 
1 row in set (0.01 sec) 

लेनदेन अलगाव स्तर करना पढ़ें-प्रतिबद्ध

mysql> SET GLOBAL tx_isolation='READ-COMMITTED'; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SET SESSION tx_isolation='READ-COMMITTED'; 
Query OK, 0 rows affected (0.00 sec) 

mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation; 
+-----------------------+----------------+ 
| @@GLOBAL.tx_isolation | @@tx_isolation | 
+-----------------------+----------------+ 
| READ-COMMITTED  | READ-COMMITTED | 
+-----------------------+----------------+ 
1 row in set (0.01 sec) 

mysql> 

और आवेदन को फिर से चलाने ...

+0

एक गरीब है उत्तर .. – 5ervant

+0

आपको कुछ और स्पष्टीकरण और कोड –

+0

लेनदेन अलगाव स्तर के व्यवहार के लिए MySQL मैन्युअल जांचें। – GuruMatics