使用python检查数据库连接是不是繁忙

Posted

技术标签:

【中文标题】使用python检查数据库连接是不是繁忙【英文标题】:Check if a database connection is busy using python使用python检查数据库连接是否繁忙 【发布时间】:2019-08-10 04:49:27 【问题描述】:

我想创建一个可以按需创建游标的数据库类。 必须可以并行使用游标(两个或多个游标可以共存),并且由于每个连接只能有一个游标,数据库类必须处理多个连接。

出于性能原因,我们希望尽可能地重用连接,并避免每次创建游标时都创建新连接: 每当发出请求时,该类都会尝试在打开的连接中找到第一个不忙的连接并使用它。

只要光标没有被消耗,连接就一直处于忙碌状态。

这是此类的一个示例:

class Database:
    ...
    def get_cursos(self,query):
        selected_connection = None

        # Find usable connection
        for con in self.connections:
            if con.is_busy() == False: # <--- This is not PEP 249
                selected_connection = con
                break

        # If all connections are busy, create a new one
        if (selected_connection is None):
            selected_connection = self._new_connection()
            self.connections.append(selected_connection)


         # Return cursor on query
         cur = selected_connection.cursor()
         cur.execute(query)
         return cur

但是查看PEP 249 标准,我找不到任何方法来检查连接是否实际被使用。

mysql 连接器等一些实现提供了检查连接是否仍有未读内容的方法(请参阅 here),但据我所知,这些不是 PEP 249 的一部分。

对于任何符合 PEP 249 的 python 数据库 API,我有什么方法可以实现之前描述的功能?

【问题讨论】:

【参考方案1】:

也许您可以使用光标的状态来告诉您是否正在使用光标。假设您有以下光标:

new_cursor = new_connection.cursor()
cursor.execute(new_query)

并且您想查看该连接是否可供另一个光标使用。您可能能够执行以下操作:

if (new_cursor.rowcount == -1):
    another_new_cursor = new_connection.cursor()
    ...

当然,这一切真正告诉你的是,自上次关闭游标以来,它还没有执行任何操作。它可以指向已完成的游标(因此连接已关闭),也可以指向刚刚创建或附加到连接的游标。另一种选择是使用 try/catch 循环,类似于:

try:
    another_new_cursor = new_connection.cursor()
except ConnectionError?: //not actually sure which error would go here but you get the idea.
    print("this connection is busy.")

当然,您可能不希望被打印的消息发送垃圾邮件,但您可以在其中做任何您想做的事情,除了阻塞、休眠 5 秒、等待传递一些其他变量、等待用户输入等. 如果你被限制在 PEP 249,你将不得不从头开始做很多事情。您是否有不能使用外部库的原因?

编辑:如果您愿意离开 PEP 249,这可能会起作用,但它可能不适合您的目的。如果你使用mysql python 库,你可以利用is_connected 方法。

new_connection = mysql.connector.connect(host='myhost',
                         database='myDB',
                         user='me',
                         password='myPassword')

...stuff happens...

if (new_connection.is_connected()):
    pass
else:
    another_new_cursor = new_connection.cursor()
    ...

【讨论】:

感谢您的回答。您的第一个解决方案是根据标准rowcount 如果接口无法确定最后一个操作的行数,则也将是-1。所以这可能是游标的问题(此外,我尝试使用 PyMSQL 在迭代游标时检索行数,我总是得到-1,即使在游标被消耗之前也是如此)。不幸的是,对于第二种解决方案,没有标准的异常可以捕获,PyMySQL 甚至没有引发一个 AFAIK。我想坚持 PEP 249,以便能够轻松更改数据库。 嗯。是的,我知道在这种情况下我唯一能看到的工作涉及使用 mysql.connector 模块,并且与您已经拥有的非常相似:if(new_connection.is_connected()): 我会继续并将其粘贴在答案中,以防万一对其他人有用,但我不知道这是否适合您的目的。我只是包装我的代码以关闭连接以防止其中出现错误,但它也应该适用于此。 问题在于......好吧,mysql库很明显只适用于mysql......所以在不改变方法的情况下不改变数据库。这是针对基于网络的项目吗? Django 对它的模型做了一些巫术,使它们与数据库无关,我敢肯定还有其他具有相同目标的东西,但你可能需要做一些挖掘才能找到它们。 最后我决定听从你的建议并使用一些更高级别的 API。我正在使用 SQLAlchemy。

以上是关于使用python检查数据库连接是不是繁忙的主要内容,如果未能解决你的问题,请参考以下文章

Python:检查 IRC 连接是不是丢失(PING PONG?)

使用 NestJs 和 Mysql 检查连接是不是成功

检查数据库连接是不是存在

支付宝系统繁忙

tp5查询卡死

配置Tomcat服务器数据连接池