【问题标题】:Python MySQLdb empty select query although manual query execution delivers resultsPython MySQLdb 空选择查询,尽管手动查询执行提供了结果
【发布时间】:2011-12-06 20:35:59
【问题描述】:

我编写了一个 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

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

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(),没有区别

我很想知道我不明白的地方。

【问题讨论】:

  • def getData(); 中的分号应该是冒号。
  • self.cursor.fetchall() 是第一次通过while-loop 还是在多次通过后返回None
  • - 是的冒号,对不起,简单的错字
  • - 它在第一次打开时给出了正确的答案,但在 while 循环期间却没有。西蒙在下面的回答解决了这个问题并且非常有意义。
  • 你读懂了我的想法,我遇到了同样的问题,但没想到其他人会遇到它:D

标签: python mysql daemon


【解决方案1】:

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

解决方案很简单:不调用db.disconnect(),而是调用dbConnection.commit(),这会结束当前事务并开始新事务。

【讨论】:

  • 感谢 Simon,这是我的数据库中唯一的 InnoDB 表,我认为它不会对 Select 语句产生影响。但显然它确实如此,我添加了 commit(),现在它完美地工作了!非常非常感谢!
  • maaaaaaaan !太棒了,我认为 db.commit() 仅用于更新内容。这救了我的命,兄弟。
【解决方案2】:

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

由于你通过数据库类处理所有事情,我猜提交代码可以去那里。

只是为西蒙所说的提供一个代码

    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循环中而不是调用新定义的函数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-09
    • 2020-05-27
    • 1970-01-01
    • 2012-12-04
    相关资源
    最近更新 更多