2008-10-16 129 views

回答

8

如果您使用的是Ubuntu Linux,则会在python-mysql软件包中添加一个修补程序,该软件包添加了设置相同MYSQL_OPT_RECONNECT选项的功能(请参阅here)。我还没有尝试过。

不幸的是,由于与自动连接和转换冲突(描述here),该补丁后来被删除。

该网页上评论说: 1.2.2-7发布的强悍 - 松开2008-06-19

中的python-MySQLdb的(1.2.2-7)不稳定的;急=低

[桑德罗托西] *的Debian /控制 - 在描述列表项线始于2的空间,以避免对网页重新格式化 (关闭:#480341)

[贝恩德Zeimetz] *于Debian /补丁/ 02_reconnect.dpatch: - 删除补丁: 评论在风暴这就解释了这个问题:

# Here is another sad story about bad transactional behavior. MySQL 
    # offers a feature to automatically reconnect dropped connections. 
    # What sounds like a dream, is actually a nightmare for anyone who 
    # is dealing with transactions. When a reconnection happens, the 
    # currently running transaction is transparently rolled back, and 
    # everything that was being done is lost, without notice. Not only 
    # that, but the connection may be put back in AUTOCOMMIT mode, even 
    # when that's not the default MySQLdb behavior. The MySQL developers 
    # quickly understood that this is a terrible idea, and removed the 
    # behavior in MySQL 5.0.3. Unfortunately, Debian and Ubuntu still 
    # have a patch right now which *reenables* that behavior by default 
    # even past version 5.0.3. 
+0

我想无论客户确实,连接丢失可能表示的损失事务(服务器电源循环)或连接丢失。所以我同意简单的重新连接可能会隐藏数据丢失与MySQL客户端用户的期望。 – 2011-07-06 17:05:27

-3

你打赌等它来解决自己掉线的代码。

一种方式做这将是以下几点:

import MySQLdb 

class DB: 
    conn = None 

    def connect(self): 
     self.conn = MySQLdb.connect() 

    def cursor(self): 
     try: 
      return self.conn.cursor() 
     except (AttributeError, MySQLdb.OperationalError): 
      self.connect() 
      return self.conn.cursor() 

db = DB() 
cur = db.cursor() 
# wait a long time for the Mysql connection to timeout 
cur = db.cursor() 
# still works 
+4

其实这个不起作用。创建游标不会与DB建立连接,因此不会抛出OperationError异常。 – Boaz 2011-09-20 15:09:24

1

我曾与MySQL和Python,并为我工作解决了类似的问题是MySQL的升级到5.0.27(在Fedora Core 6;你​​的系统可以用不同的版本正常工作)。我试了很多其他的东西,包括修补Python库,但升级数据库要容易得多,(我认为)是一个更好的决定。

65

我通过创建一个包装cursor.execute()方法的函数解决了这个问题,因为这是抛出MySQLdb.OperationalError异常的原因。上面的另一个例子意味着它引发这个异常的方法是conn.cursor()

import MySQLdb 

class DB: 
    conn = None 

    def connect(self): 
    self.conn = MySQLdb.connect() 

    def query(self, sql): 
    try: 
     cursor = self.conn.cursor() 
     cursor.execute(sql) 
    except (AttributeError, MySQLdb.OperationalError): 
     self.connect() 
     cursor = self.conn.cursor() 
     cursor.execute(sql) 
    return cursor 

db = DB() 
sql = "SELECT * FROM foo" 
cur = db.query(sql) 
# wait a long time for the Mysql connection to timeout 
cur = db.query(sql) 
# still works 
+0

不错的答案! – 2013-01-17 05:53:56

+1

@ garret-heaton - 为什么重新连接AttributeError?当连接变得陈旧时,这也会抛出吗? – aaa90210 2014-07-14 00:14:23

3

你可以分开提交和关闭连接......这不是可爱的,但它做到了。

class SqlManager(object): 
""" 
Class that handle the database operation 
""" 
def __init__(self,server, database, username, pswd): 

     self.server = server 
     self.dataBase = database 
     self.userID = username 
     self.password = pswd 

def Close_Transation(self): 
     """ 
     Commit the SQL Query 
     """ 
     try: 
     self.conn.commit() 
     except Sql.Error, e: 
     print "-- reading SQL Error %d: %s" % (e.args[0], e.args[1]) 

def Close_db(self): 
    try: 
     self.conn.close() 
    except Sql.Error, e: 
     print "-- reading SQL Error %d: %s" % (e.args[0], e.args[1]) 

def __del__(self): 
    print "close connection with database.." 
    self.conn.close() 
相关问题