2011-10-13 21 views
6

प्रदान करता है मैंने एक पायथन डिमन लिखा है जो लगातार एक mysql डेटाबेस का चुनाव करता है। यह ठीक काम करता है जब मैं लगातार कनेक्ट और प्रश्नों के बीच डेटाबेस से पुन: कनेक्ट इस प्रकार है:पायथन MySQLdb खाली चयन क्वेरी हालांकि मैन्युअल क्वेरी निष्पादन परिणाम

def connect(self): 
    self.connection = MySQLdb.connect(...) 
    self.cursor = self.connection.cursor() 
    return self.cursor 

def disconnect(self): ... 
    self.cursor.close() 
    self.connection.close() 

def getData(); .... 
    sqlcmd = """SELECT ....""" 
    self.cursor.execute (sqlcmd % (params)) 
    result = self.cursor.fetchall() 
    return result 

if __name__ == "__main__": 
    db = prepaid_db.Database() 
    while 1: 
     dbConnection = db.connect() 
     data = db.getData() 
     ... do stuff 
     db.disconnect 

लेकिन जब मैं डेटाबेस कनेक्शन खुला रखने की कोशिश (नीचे के रूप में) मैं यह है, जबकि, एक खाली क्वेरी मिल भले ही, चल रहा है मैं मैन्युअल रूप से डीबी से पूछताछ कर सकता हूं, इसे एक ही प्रश्न दे सकता हूं और परिणाम प्राप्त कर सकता हूं।

if __name__ == "__main__": 
    db = prepaid_db.Database() 
    dbConnection = db.connect() 
    while 1: 
     data = db.getData() 
     ... do stuff 
    db.disconnect 

मैं समझने के लिए क्यों यह इस करना होगा सब कुछ कोशिश की है:

  • विकलांग क्वेरी कैश और मामले mysql कैश में प्रश्न में जोड़ा यादृच्छिक एक्स = एक्स मिलती-जुलती क्वेरी से उलझन में था
  • सक्षम mysql क्वेरी लॉगिंग: क्वेरी के माध्यम से आता है लेकिन अभी भी एक खाली सेट
  • database.connect को cursor.connect ले जाया देता है, और GetData(), कोई फर्क नहीं
में वापस

मुझे एक सुराग पसंद आएगा जो मुझे समझ में नहीं आ रहा है।

+0

'def getData() में अर्धविराम; 'एक कोलन होना चाहिए। – unutbu

+0

क्या 'self -ursor.fetchall() '' while-loop' के माध्यम से पहली बार' कोई नहीं ', या कई पास के बाद? – unutbu

+0

- हाँ कोलन पर, क्षमा करें, सरल टाइपो –

उत्तर

6

आप शायद एक इनो डीबी तालिका से पूछताछ कर रहे हैं जहां एक और प्रक्रिया इस दौरान नए डेटा को सम्मिलित करती है। यदि ऐसा है, तो MySQL सेवर स्वचालित रूप से आपके कनेक्शन के लिए एक नया लेनदेन शुरू करता है, और चूंकि आप कहीं भी dbConnection.commit() या .rollback() पर कॉल नहीं करते हैं, तो आप हमेशा उस लेनदेन में फंस जाते हैं। InnoDB की डिफ़ॉल्ट सेटिंग्स सुनिश्चित करें कि जब भी आप डेटा पूछते हैं, तो आप हमेशा एक ही लेनदेन के भीतर एक ही परिणाम देखेंगे। तो तालिका में डालने वाली कुछ अन्य प्रक्रिया आपके डेमन के कनेक्शन से छिपी हुई है।

समाधान सरल है: db.disconnect() पर कॉल करने के बजाय, dbConnection.commit() पर कॉल करें, जो वर्तमान को समाप्त करता है और एक नया लेनदेन शुरू करता है।

+3

वहां प्रतिभाशाली लोग! –

+0

धन्यवाद साइमन, यह मेरी डीबी में एकमात्र InnoDB तालिका थी और मुझे नहीं लगता था कि इसका चयन कथन पर असर होगा। लेकिन स्पष्ट रूप से यह करता है, मैंने प्रतिबद्ध() जोड़ा और अब यह पूरी तरह से काम करता है! बहुत बहुत धन्यवाद! –

+0

मायाअन! वह कमाल था, मैंने सोचा था कि db.commit() केवल सामान अपडेट करने के लिए है। उसने मेरे जीवन को बचाया। – AliBZ

2

MySQLdb.cursor ऑब्जेक्ट शायद MySQLDB manual में दी गई प्रतिबद्धता का समर्थन नहीं करता है। दूसरी तरफ कनेक्शन ऑब्जेक्ट्स करते हैं।

चूंकि आप डेटाबेस कक्षा के माध्यम से सब कुछ संभालते हैं, मुझे लगता है कि प्रतिबद्ध कोड वहां जा सकता है।

बस क्या साइमन ने कहा है

def connect(self): 
     self.connection = MySQLdb.connect(...) 
     self.cursor = self.connection.cursor() 

    def disconnect(self): ... 
     self.cursor.close() 
     self.connection.commit() 
     self.connection.close() 

    def commit(self): 
     self.connection.commit() 

    def getData(self): .... 
     sqlcmd = """SELECT ....""" 
     self.cursor.execute (sqlcmd % (params)) 
     result = self.cursor.fetchall() 
     return result 

if __name__ == "__main__": 
    db = prepaid_db.Database() 
    db.connect() 
    while 1: 
     data = db.getData() 
     ... do stuff 
     db.commit() 
    db.disconnect() 

मुझे यकीन है कि नहीं कर रहा हूँ के लिए एक कोड देने के लिए, लेकिन शायद आप भी तरह

db.connection.commit() 

कुछ देर के पाश में बजाय नव निर्धारित फ़ंक्शन कॉल करने के लिए कर सकते हैं

+0

धन्यवाद RebBaron, यह ठीक है कि मैंने इसे कैसे किया था। –

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