2011-11-09 23 views
12

SQL veritabanlarıyla uğraşmak için python'un SQLite arabiriminde (şımarık mı?) Kullanıyorum. Python'un SQLite's API'sinde bir güzel özellik olan "context manager", yani python'un with beyanı. Genellikle şu şekilde sorguları çalıştırın: benim sorgu veritabanı değiştirir, yukarıdaki kod ilePython'un MySQLdb için içerik yöneticisi

import as sqlite 

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

ve ben conn.commit() çalıştırmayı unutma, bağlam yöneticisi with deyimi çıkarken otomatik benim için çalışır. Ayrıca özel durumları da güzelce ele alır: Bir şey yapmadan önce bir istisna olursa, veritabanı geri alınır.

Şu anda kutudan çıkmış benzer bir içerik yöneticisini desteklemiyor gibi görünen MySQLdb arabirimini kullanıyorum. Kendim nasıl oluşturabilirim? İlgili bir soru here var, ancak tam bir çözüm sunmuyor.

cevap

15

MySQLdb bağlantılarının artık içerik yöneticileri olduğunu unutmayın. Bakınız user2966041's answer.


Böyle bir şey kullanabilirsiniz:

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) 

Kullanmak için size PYTHONPATH içinde config.py yerleştirip, kullanıcı ana tanımlamak, orada, MYDB değişkenleri PASS olacaktır. Bunun yerine oursql kullanarak düşünebilirsiniz

with some_connection as cursor: 
    do_something_with(cursor) 

:

Not Ayrıca oursql inşa with yapı ile gelir MySQL için alternatif bir sürücüdür.

+0

Mükemmel çözüm! Sadece MySQLdb için cevap vermediniz, aynı zamanda diğer sürücülerle de kullanılabilir. Ayrıca, bizimsql umut verici görünüyor. Teşekkürler. – conradlee

+0

@MMartins: Düzeltme için çok teşekkürler. – unutbu

17

Bu soru ilk olarak sorulduğundan beri bazı şeyler değişti. Biraz kafa karıştırıcı (en azından bakış açımdan), MySQLdb'un son sürümleri için, bir bağlamda bir bağlantı kullanırsanız, bir imleci alırsınız (oursql örneğine göre), otomatik olarak kapanacak bir şey değil (eğer açarsanız örneğin bir dosya).

İşte böyle yapar:

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

Otomatik taahhüt mü? Otomatik işlem modunda olduğu gibi, hiç işleminiz yok mu? – Halfgaar

İlgili konular