Python MySQLdb空选择查询,尽管手动查询执行提供结果

时间:2011-10-13 10:32:05

标签: python mysql daemon

我编写了一个python守护进程,它不断轮询mysql数据库。当我在查询之间连续连接并重新连接到数据库时,它工作正常,如下所示:

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

但是当我尝试保持数据库连接打开时(如下所示),我得到一个空查询,即使在它运行时我可以手动查询数据库,给它相同的查询并得到我期望的结果。 / p>

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

我已经尝试了一切,以了解它为什么会这样做:

  • 禁用查询缓存并在查询中添加随机x = x,以防mysql缓存被类似查询混淆
  • 启用了mysql查询日志记录:查询通过但仍返回空集
  • 将cursor.connect移动到database.connect,然后返回到getData(),没有区别

我想知道我不理解的事情。

2 个答案:

答案 0 :(得分:9)

您可能正在查询InnoDB表,其中另一个进程在此期间插入新数据。如果是这种情况,MySQL服务器会自动为您的连接启动新事务,并且由于您未在任何地方调用dbConnection.commit().rollback(),因此您将永远陷入该事务中。 InnoDB的默认设置确保无论何时查询数据,您都将在一个事务中看到相同的结果。因此,无论其他进程插入到表中,都会对守护进程的连接隐藏。

解决方案很简单:不要拨打db.disconnect(),而是拨打dbConnection.commit(),结束当前并开始新的交易。

答案 1 :(得分:2)

MySQLdb.cursor对象可能不支持MySQLDB manual中给出的提交。另一方面,连接对象可以。

由于您通过Database类处理所有内容,我想提交代码可以去那里。

只是为Simon所说的代码提供代码

    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()
在while循环中

而不是调用新定义的函数