我对 Python 及其 MySQLdb 连接器有点陌生。 我正在编写一个 API 以使用 RESTful 方法从数据库返回一些数据。在 PHP 中,我将连接管理部分包装在一个类中,充当 MySQL 查询的抽象层。
在 Python 中:
我在脚本的早期定义连接:
/li>con = mdb.connect('localhost', 'user', 'passwd', 'dbname')
然后,在所有后续方法中:
import MySQLdb as mdb def insert_func(): with con: cur = con.cursor(mdb.cursors.DictCursor) cur.execute("INSERT INTO table (col1, col2, col3) VALUES (%s, %s, %s)", (val1, val2, val3) ) rows = cur.fetchall() #do something with the results return someval
等等
我使用
mdb.cursors.DictCursor
,因为我更喜欢能够以关联数组的方式访问数据库列。
现在问题开始出现了:
在一个函数中,我发出插入查询以创建具有唯一“groupid”的“组”。
这个“组”有一个创建者。数据库中的每个用户都在表中他/她的行的“组”列中保存一个 JSON 数组。
所以当我创建一个新组时,我想将 groupid 分配给创建它的用户。
我使用类似的函数更新用户的记录。
我将“插入”和“更新”部分包装在两个单独的函数定义中。
我第一次运行脚本时,一切正常。
我第二次运行该脚本时,该脚本无休止地运行(我怀疑是由于与 MySQL 数据库的某些空闲连接所致)。
当我使用 CTRL + C 中断它时,出现以下错误之一:
- “‘游标’对象没有属性‘连接’”
- “命令不同步;您现在无法运行此命令”
- 或预期的任何其他 KeyboardInterrupt 异常。
在我看来,这些错误是由我的代码中处理连接和游标的某些错误方式引起的。
我读到使用 with con:
是一种很好的做法,这样连接将在查询后自动关闭。我在每个函数中对 'con' 使用 'with',因此连接已关闭,但我决定全局定义连接,以便任何函数使用它。这似乎与 with con:
上下文管理不兼容。我怀疑游标需要以类似的方式进行“上下文管理”,但我不知道该怎么做(据我所知,PHP 不对 MySQL 使用游标,因此我没有使用它们的经验)。
我现在有以下问题:
为什么第一次可以,第二次不行? (但是,在 CTRL + C 中断后,它会再次工作一次)。
在使用多个函数(可以按顺序调用)时,我应该如何使用连接和游标?
最佳答案
我认为这里有两个主要问题 - 一个似乎是 python 代码,另一个是您如何与数据库交互的结构。
首先,您没有关闭连接。这取决于您的应用程序的需求——您必须决定它应该保持打开状态多长时间。引用 this SO question
from contextlib import closing
with closing( connection.cursor() ) as cursor:
... use the cursor ...
# cursor closed. Guaranteed.
connection.close()
现在,您必须使用 Ctl+C
中断您的程序,因为没有理由让您的 with
语句停止运行。
其次,开始从“事务”的角度考虑您与数据库的交互。做一些事情,将它提交给数据库,如果它不起作用,则回滚,如果它起作用,则关闭连接。 Here's a tutorial .
关于python - 在 Python 中跨多个函数使用 MySQLdb 连接和游标的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30288497/