2011-11-09 44 views
12

của Python Tôi đang sử dụng để (hư hỏng bởi?) Giao diện SQLite của python để xử lý cơ sở dữ liệu SQL. Một tính năng thú vị trong API SQLite của python là "trình quản lý ngữ cảnh", tức là, câu lệnh with của python. Tôi thường thực hiện các truy vấn theo cách sau:Trình quản lý ngữ cảnh cho MySQLdb

import as sqlite 

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

Với đoạn mã trên, nếu truy vấn của tôi sẽ thay đổi cơ sở dữ liệu và tôi quên để chạy conn.commit(), người quản lý bối cảnh chạy nó cho tôi tự động khi thoát khỏi tuyên bố with. Nó cũng xử lý ngoại lệ độc đáo: nếu một ngoại lệ xảy ra trước khi tôi cam kết bất cứ điều gì, sau đó cơ sở dữ liệu được cuộn lại.

Tôi hiện đang sử dụng giao diện MySQLdb, có vẻ như không hỗ trợ trình quản lý ngữ cảnh tương tự ra khỏi hộp. Làm thế nào để tạo của riêng tôi? Có một câu hỏi liên quan here, nhưng nó không cung cấp một giải pháp hoàn chỉnh.

Trả lời

15

Lưu ý rằng các kết nối MySQLdb hiện là các trình quản lý ngữ cảnh. Xem user2966041's answer.


Bạn có thể sử dụng một cái gì đó như thế này:

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) 

Để sử dụng nó, bạn sẽ đặt config.py ở PYTHONPATH của bạn và xác định các HOST, USER, PASS, biến MYDB đó.

Cũng lưu ý rằng oursql là một trình điều khiển thay thế cho MySQL mà đi kèm với các with xây dựng xây dựng trong:

with some_connection as cursor: 
    do_something_with(cursor) 

Bạn có thể muốn xem xét sử dụng oursql để thay thế.

+0

Giải pháp tuyệt vời! Bạn không chỉ đưa ra câu trả lời cho MySQLdb, nó cũng có thể được sử dụng với các trình điều khiển khác. Ngoài ra, oursql trông đầy hứa hẹn. Cảm ơn. – conradlee

+0

@MMartins: Cảm ơn rất nhiều vì đã sửa. – unutbu

17

Hãy suy nghĩ mọi thứ đã thay đổi vì câu hỏi này ban đầu được hỏi. Hơi khó hiểu (theo quan điểm của tôi ít nhất), đối với các phiên bản gần đây của MySQLdb, nếu bạn sử dụng kết nối trong ngữ cảnh bạn sẽ có con trỏ (theo ví dụ oursql), không phải cái gì đó tự động đóng (như bạn đã mở một tập tin ví dụ).

Dưới đây là những gì tôi làm:

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

Tự động cam kết? Như trong, chế độ tự động cam kết, vì vậy bạn không có giao dịch? – Halfgaar

Các vấn đề liên quan