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

时间:2019-03-19 15:36:33

标签: python mysql sql pymysql mysql-connector-python

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

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

只要没有消耗游标,连接仍然很忙。

以下是此类的示例:

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 Connector)提供了一些方法来检查连接是否仍未读取内容(请参阅here),但据我所知,这些都不属于PEP 249。

有没有一种方法可以实现针对任何符合PEP 249的python数据库API的描述?

1 个答案:

答案 0 :(得分: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()
    ...