Python MySQLDB查询未返回所有行
我正在尝试在Python中使用MySQLDB进行简单的获取 我有两张表(客户和产品)。我必须查找Accounts表,从中获取Accu id并使用它查询Products表 Products表有10多行。但当我运行这段代码时,每次运行它都会随机返回0到6行 下面是代码片段:Python MySQLDB查询未返回所有行,python,mysql,python-2.7,Python,Mysql,Python 2.7,我正在尝试在Python中使用MySQLDB进行简单的获取 我有两张表(客户和产品)。我必须查找Accounts表,从中获取Accu id并使用它查询Products表 Products表有10多行。但当我运行这段代码时,每次运行它都会随机返回0到6行 下面是代码片段: # Set up connection con = mdb.connect('db.xxxxx.com', 'user', 'password', 'mydb') # Create cursor cur = con.curso
# Set up connection
con = mdb.connect('db.xxxxx.com', 'user', 'password', 'mydb')
# Create cursor
cur = con.cursor()
# Execute query
cur.execute("SELECT acc_id FROM Accounts WHERE ext_acc = '%s'" % account_num ) # account_num is alpha-numberic and is got from preceding part of the program
# A tuple is returned, so get the 0th item from it
acc_id = cur.fetchone()[0]
print "account_id = ", acc_id
# Close the cursor - I was not sure if I can reuse it
cur.close()
# Reopen the cursor
cur = con.cursor()
# Second query
cur.execute("SELECT * FROM Products WHERE account_id = %d" % acc_id)
keys = cur.fetchall()
print cur.rowcount # This prints incorrect row count
for key in keys: # Does not print all rows. Tried to directly print keys instead of iterating - same result :(
print key
# Closing the cursor & connection
cur.close()
con.close()
奇怪的是,我尝试使用调试器(Eclipse上的PyDev)单步执行代码,它正确地获取了所有行(存储在变量“keys”中的值以及控制台输出都是正确的)
我确信我的数据库有正确的数据,因为我在MySQL控制台上运行了相同的SQL&得到了正确的结果
为了确保没有错误地关闭连接,我尝试使用con而不是手动关闭连接,结果是一样的
我做了,但我找不到太多的帮助我解决这个问题
我哪里做错了
多谢各位
编辑:我现在注意到另一件奇怪的事情。排队
cur.execute(“从帐户id=%d”%acc\u id)的产品中选择*”
,我硬编码了acc\u id值,即
cur.execute(“SELECT*FROM Products WHERE account\u id=%d”%322)
并返回所有行这实际上不是一个答案,只是试图从与RBK的聊天中收集所有信息,排除了一系列潜在问题,但仍然没有给出解释或解决方案,希望其他人能发现问题或想出其他办法来尝试
这显然是这一行的内容:
cur.execute("SELECT * FROM Products WHERE account_id = %d" % acc_id)
特别是因为用322
代替acc\u id
解决了所有问题。(如下所示。)
实际上,这条线路有两个问题,可能会造成阻碍。您总是希望使用DB-API绑定,而不是字符串格式(以及任何其他语言中的等效格式),以避免SQL注入攻击、正确转义/转换等,并提高效率。此外,DB-ABI绑定和字符串格式都需要参数的元组,而不是单个参数。(出于传统原因,单个参数通常有效,但有时无效,调试时会产生混乱……最好不要这样做。)因此,这应该是:
cur.execute("SELECT * FROM Products WHERE account_id = %d", (acc_id,))
不幸的是,在聊天中讨论了这一点,让你尝试了很多东西之后,我们无法找到这里的真正错误。总结我们的尝试:
cur.execute("SELECT COUNT(*) FROM Devices WHERE account_id = %s" , (333,))
print cur.fetchone()[0]
print 'account id =', acc_id
print type(acc_id)
cur.execute("SELECT COUNT(*) FROM Devices WHERE account_id = %s" , (acc_id,))
print cur.fetchone()[0]
于是,我们尝试:
cur.execute("SELECT COUNT(*) FROM Devices WHERE account_id = %s" , (333,))
print cur.fetchone()[0]
print 'account id =', acc_id
print type(acc_id)
cur.execute("SELECT COUNT(*) FROM Devices WHERE account_id = %s" , (acc_id,))
print cur.fetchone()[0]
结果是:
10
account id = 333
<type 'long'>
2
10
帐户id=333
2.
重复运行时,最后一个数字在0-6之间变化,而第一个数字始终为10。使用acc\u id
与使用333
没有什么不同,但事实确实如此。为了防止一个查询以某种方式“感染”下一个查询,如果没有前两行,其余查询的工作方式相同
因此,使用acc\u id
可能与使用333
不同。然而,事实确实如此
在聊天过程中的某个时刻,我们显然从产品转移到了设备,从322转移到了333,但不管怎样,上面显示的测试肯定完全按照所示进行,并且返回了不同的结果
也许他有一个错误的或安装不好的MySQLDb版本。他将尝试寻找一个较新的版本,或者其他一个Python MySQL库,看看它是否会有所不同
在这一点上,我下一个最好的猜测是RBK无意中激怒了一些技术高超的恶作剧之神,但我甚至想不出其中一个是我脑子里想出来的。我有点明白了这个问题。最后很傻。这是一个比赛条件
这就是我实际代码的组织方式:
Code Block2
{The code I had posted in my question}
问题是API(在代码块1中调用)花了几秒钟时间将10个条目添加到产品表中
当我的代码(代码块2)运行一个获取查询时,所有的10行都没有添加,因此获取了0到6行(当时添加了多少行)
为了解决这个问题,我在执行SQL查询之前让代码休眠了5秒钟:
Code Block 1
time.sleep(5)
Code Block 2
当我硬编码acc_id时,它工作的原因是,我硬编码的acc_id来自一个宝贵的执行(每次运行都返回一个新的acc_id)。
它在通过调试器时工作的原因是,手动单步执行就像给它一个睡眠时间
对我来说,这是一个教训,让我了解一些API的内部工作(即使它们被认为像一个黑匣子),并在下次遇到类似问题时思考这样的竞争条件 fethall()
是一件事吗<代码>场效应晶体管*c*霍尔()?这有区别吗?还有,你说这个表有10多行。。。你在考虑你的where子句吗?哎呀!fethall()是我在这里发布的代码中的一个输入错误!在我的IDE中找到正确的:)在我的问题中更正它。。是的,我在考虑where条款。同一个查询在mysql控制台上逐字返回10行。@Droogans,我现在已经删除了关闭和重新打开我机器上代码上的光标……但它仍然不起作用?我假设,既然你没说,@RBK:不,(acc\u id)
不是一个元组,它和acc\u id
是一样的。如果您想要一个1项元组
,您需要添加一个逗号,如我上面的示例所示:(acc\u id,)
。同样,你不应该在这里使用%
。谢谢你的帖子。设备和产品是相同的。我在这里发布问题时使用了products作为别名,因为我不想使用与我们的db工作时使用的名称相同的名称:)