我是Python及其MySQLdb连接器的新手。 我正在编写API以使用RESTful方法从数据库返回一些数据。在PHP中,我将Connection管理部分包装在一个类中,充当MySQL查询的抽象层。
我在脚本的早期定义了连接: 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分配给创建它的用户。
我使用类似的功能更新用户的记录。
我已经将'插入'并且'更新'两个单独的函数defs中的部分。
我第一次运行脚本时,一切正常。
第二次运行脚本时,脚本无休止地运行(我怀疑是由于与MySQL数据库的一些空闲连接)。
当我使用CTRL + C打断它时,我收到以下错误之一:
在我看来,这些错误是由我的代码中处理连接和游标的一些错误方法引起的。
我认为使用with con:
是一种很好的做法,这样连接会在查询后自动关闭。我使用'' on' con'在每个函数中,所以连接已关闭,但我决定全局定义连接,以便任何函数使用它。这似乎与with con:
上下文管理不兼容。我怀疑光标需要被上下文管理'以类似的方式,但我不知道如何做到这一点(据我所知,PHP没有使用游标的MySQL,所以我没有使用它们的经验。)
我现在有以下问题:
为什么它第一次有效而不是第二次? (然而,在CTRL + C中断之后,它会再次工作一次。)
使用多个函数(可以按顺序调用)时,如何使用连接和游标?
答案 0 :(得分:0)
我认为这里有两个主要问题 - 一个似乎是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
答案 1 :(得分:0)
使用连接,与文件一样处理rule of thumb is open late, close early.
所以我建议只在他们尝试做一件事的地方分享联系。或者,如果您进行多处理,则每个进程都会获得一个连接,然后再次打开,然后提前关闭。如果你在循环外打开和关闭顺序操作(比如循环)。拥有全球联系可能会变得混乱。主要是因为现在你必须跟踪哪个函数在什么时候使用它,以及它尝试用它做什么。
“现在无法运行命令”的问题,是因为键盘中断会导致活动连接中断。
关于你的问题的第一部分 - 无休止地可以在任何地方。 python的每个实例都将获得自己的连接。因此,当你第二次运行它时,它应该得到自己的连接。打开一个mysql客户端并执行
show full processlist
看看最近发生了什么。