使用 MySQL.connector 和 Twisted Python 来执行多个查询
Using MySQL.connector with Twisted Python to execute multiple queries
我最近有一个 Python 2.7x 项目,我需要使用 mysql.connector 在一个查询中执行多个分号分隔的语句。这在 .
中有很好的解释
但是,我需要将 mysql.connector 与 Twisted 一起用于我当前的项目,这意味着使用 Twisted 出色的 enterprise.adbapi 模块使我的新阻塞数据库连接成为非阻塞。
config = {"user": username, "password": password, "host": hostname,
"database": database_name, "raise_on_warnings": True}
cp = adbapi.ConnectionPool("mysql.connector", **config)
我的测试语句定义如下。我很抱歉他们是一个有点无聊的例子,但我知道我期望的结果,这应该足以验证我得到了多个语句的结果。
statement1 = "SELECT * FROM queue WHERE id = 27;"
statement2 = "SELECT * FROM order WHERE id = 1;"
statement_list = [statement1, statement2]
statements = " ".join(statement_list)
当我现在尝试执行 ConnectionPool 方法 .runQuery() 时出现问题
def _print_result(result):
if result:
print("this is a result")
print(result)
else:
print("no result")
reactor.stop()
d = cp.runQuery(statements, multi=True)
d.addBoth(_print_result)
这让我得到以下结果:
this is a result [Failure instance: Traceback: : No result set to fetch from.
如何使用 Twisted 的 adbapi 模块获得我知道的结果?
所以,事实证明,当使用 adbapi.ConnectionPool.runQuery() 时,默认行为是将数据库查询的结果发送到 cursor.fetchall() 方法。但是,当使用 mysql.connector 时,这不起作用,即使没有扭曲。相反,需要遍历结果集,并对集合的每个成员调用 fetchall()。
所以,我解决这个问题的方法是使用以下子类。
from twisted.enterprise import adbapi
class NEWadbapiConnectionPool(adbapi.ConnectionPool):
def __init__(self, dbapiName, *connargs, **connkw):
adbapi.ConnectionPool.__init__(self, dbapiName, *connargs, **connkw)
def runMultiQuery(self, *args, **kw):
return self.runInteraction(self._runMultiQuery, *args, **kw)
def _runMultiQuery(self, trans, *args, **kw):
result = trans.execute(*args, **kw)
result_list = []
for item in result:
if item.with_rows:
result_list.append(item.fetchall())
return result_list
所以现在我创建以下内容:
def _print_result(result):
if result:
print("this is a result")
print(result)
else:
print("no result")
reactor.stop()
cp = NEWadbapiConnectionPool("mysql.connector", **config)
d = cp.runMultiQuery(statements, multi=True)
d.addBoth(_print_result)
并获取每个语句的结果列表。
我希望其他人觉得这很有用。
RunQuery 总是需要结果。正确的方法是调用不获取结果的 runOperation()。
如果您想使用 .runQuery,它需要获取结果,所以您需要 return 一些东西
dbpool.runQuery(
"UPDATE something SET col1=true WHERE some_id=123 RETURNING *"
)
.runOperation 不期望结果
dbpool.runOperation(
"UPDATE something SET col1=true WHERE some_id=123"
)
我最近有一个 Python 2.7x 项目,我需要使用 mysql.connector 在一个查询中执行多个分号分隔的语句。这在
但是,我需要将 mysql.connector 与 Twisted 一起用于我当前的项目,这意味着使用 Twisted 出色的 enterprise.adbapi 模块使我的新阻塞数据库连接成为非阻塞。
config = {"user": username, "password": password, "host": hostname, "database": database_name, "raise_on_warnings": True} cp = adbapi.ConnectionPool("mysql.connector", **config)
我的测试语句定义如下。我很抱歉他们是一个有点无聊的例子,但我知道我期望的结果,这应该足以验证我得到了多个语句的结果。
statement1 = "SELECT * FROM queue WHERE id = 27;" statement2 = "SELECT * FROM order WHERE id = 1;" statement_list = [statement1, statement2] statements = " ".join(statement_list)
当我现在尝试执行 ConnectionPool 方法 .runQuery() 时出现问题
def _print_result(result): if result: print("this is a result") print(result) else: print("no result") reactor.stop() d = cp.runQuery(statements, multi=True) d.addBoth(_print_result)
这让我得到以下结果:
this is a result [Failure instance: Traceback: : No result set to fetch from.
如何使用 Twisted 的 adbapi 模块获得我知道的结果?
所以,事实证明,当使用 adbapi.ConnectionPool.runQuery() 时,默认行为是将数据库查询的结果发送到 cursor.fetchall() 方法。但是,当使用 mysql.connector 时,这不起作用,即使没有扭曲。相反,需要遍历结果集,并对集合的每个成员调用 fetchall()。
所以,我解决这个问题的方法是使用以下子类。
from twisted.enterprise import adbapi
class NEWadbapiConnectionPool(adbapi.ConnectionPool):
def __init__(self, dbapiName, *connargs, **connkw): adbapi.ConnectionPool.__init__(self, dbapiName, *connargs, **connkw) def runMultiQuery(self, *args, **kw): return self.runInteraction(self._runMultiQuery, *args, **kw) def _runMultiQuery(self, trans, *args, **kw): result = trans.execute(*args, **kw) result_list = [] for item in result: if item.with_rows: result_list.append(item.fetchall()) return result_list
所以现在我创建以下内容:
def _print_result(result): if result: print("this is a result") print(result) else: print("no result") reactor.stop() cp = NEWadbapiConnectionPool("mysql.connector", **config) d = cp.runMultiQuery(statements, multi=True) d.addBoth(_print_result)
并获取每个语句的结果列表。
我希望其他人觉得这很有用。
RunQuery 总是需要结果。正确的方法是调用不获取结果的 runOperation()。
如果您想使用 .runQuery,它需要获取结果,所以您需要 return 一些东西
dbpool.runQuery(
"UPDATE something SET col1=true WHERE some_id=123 RETURNING *"
)
.runOperation 不期望结果
dbpool.runOperation(
"UPDATE something SET col1=true WHERE some_id=123"
)