2011-11-09 17 views
12

के लिए संदर्भ प्रबंधक का उपयोग SQL डेटाबेस से निपटने के लिए पाइथन के SQLite इंटरफ़ेस में किया गया है (खराब हो गया है?)। पायथन के SQLite के एपीआई में "संदर्भ प्रबंधक," यानी, पायथन का with कथन में एक अच्छी सुविधा। मैं आमतौर पर निम्नलिखित तरीके से प्रश्नों निष्पादित करें: उपरोक्त कोड के साथपाइथन के MySQLdb

import as sqlite 

with sqlite.connect(db_filename) as conn: 
    query = "INSERT OR IGNORE INTO shapes VALUES (?,?);" 
    results = conn.execute(query, ("ID1","triangle")) 

, अगर मेरे क्वेरी डेटाबेस को संशोधित करता है और मैं conn.commit() चलाने के लिए भूल जाते हैं, संदर्भ प्रबंधक यह मेरे लिए स्वचालित रूप से with बयान से बाहर निकलने पर चलाता है। यह अपवादों को अच्छी तरह से संभालता है: यदि कुछ भी करने से पहले अपवाद होता है, तो डेटाबेस वापस लुढ़का जाता है।

अब मैं MySQLdb इंटरफ़ेस का उपयोग कर रहा हूं, जो बॉक्स के बाहर एक समान संदर्भ प्रबंधक का समर्थन नहीं करता है। मैं अपना खुद का निर्माण कैसे करूं? एक संबंधित प्रश्न here है, लेकिन यह एक पूर्ण समाधान प्रदान नहीं करता है।

उत्तर

15

ध्यान दें कि MySQLdb कनेक्शन अब पहले से ही संदर्भ प्रबंधक हैं। user2966041's answer देखें।


आप कुछ इस तरह इस्तेमाल कर सकते हैं:

import config 
import MySQLdb 
import MySQLdb.cursors as mc 
import _mysql_exceptions 
DictCursor = mc.DictCursor 
SSCursor = mc.SSCursor 
SSDictCursor = mc.SSDictCursor 
Cursor = mc.Cursor 


class Cursor(object): 
    def __init__(self, 
       cursorclass=Cursor, 
       host=config.HOST, user=config.USER, 
       passwd=config.PASS, dbname=config.MYDB, 
       driver=MySQLdb, 
       ): 
     self.cursorclass = cursorclass 
     self.host = host 
     self.user = user 
     self.passwd = passwd 
     self.dbname = dbname 
     self.driver = driver 
     self.connection = self.driver.connect(
      host=host, user=user, passwd=passwd, db=dbname, 
      cursorclass=cursorclass) 
     self.cursor = self.connection.cursor() 

    def __iter__(self): 
     for item in self.cursor: 
      yield item 

    def __enter__(self): 
     return self.cursor 

    def __exit__(self, ext_type, exc_value, traceback): 
     self.cursor.close() 
     if isinstance(exc_value, Exception): 
      self.connection.rollback() 
     else: 
      self.connection.commit() 
     self.connection.close() 

with Cursor() as cursor: 
    print(cursor) 
    connection = (cursor.connection) 
    print(connection) 

इसका इस्तेमाल करने के लिए आप अपने PYTHONPATH में config.py जगह है और उपयोगकर्ता होस्ट परिभाषित करते हैं, चाहते हैं, वहाँ पास, mydb चर।

with some_connection as cursor: 
    do_something_with(cursor) 

इसके बजाय आप oursql उपयोग करने पर विचार करना चाह सकते हैं:

भी ध्यान रखें कि oursql कि with निर्माण में बनाया के साथ आता है MySQL के लिए एक विकल्प के ड्राइवर है।

+0

उत्कृष्ट समाधान! आपने केवल MySQLdb का उत्तर नहीं दिया, इसका उपयोग अन्य ड्राइवरों के साथ भी किया जा सकता है। इसके अलावा, oursql आशाजनक लग रहा है। धन्यवाद। – conradlee

+0

@MMartins: सुधार के लिए बहुत बहुत धन्यवाद। – unutbu

17

सोचें कि इस प्रश्न को मूल रूप से पूछा गया था क्योंकि चीजें बदल गई हैं। कुछ हद तक भ्रमित (कम से कम मेरे दृष्टिकोण से), MySQLdb के हाल के संस्करणों के लिए, यदि आप किसी संदर्भ में कनेक्शन का उपयोग करते हैं तो आपको कर्सर (oursql उदाहरण के अनुसार) प्राप्त होता है, जो कुछ स्वचालित रूप से बंद नहीं होता है (जैसा कि आप खोलेंगे उदाहरण के लिए एक फाइल)।

यहाँ मैं क्या करना है:

from contextlib import closing 
with closing(getConnection()) as conn: #ensure that the connection is closed 
    with conn as cursor:    #cursor will now auto-commit 
     cursor.execute('SELECT * FROM tablename') 
+0

ऑटो प्रतिबद्ध? जैसा कि ऑटो प्रतिबद्ध मोड है, तो आपके पास कोई लेनदेन नहीं है? – Halfgaar

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