我正在尝试使用python中的mysqldb进行简单的获取。
我有两张桌子(账户和产品)。我必须查找accounts表,从中获取acc_id并使用它查询products表。
products表有10多行。但当我运行这段代码时,每次运行它时,它会随机返回0到6行。
下面是代码片段:
# 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中的值和控制台输出都是正确的)。
我确信我的数据库有正确的数据,因为我在my sql控制台上运行了相同的sql并得到了正确的结果。
为了确保没有错误地关闭连接,我尝试使用
with con
而不是手动关闭连接,结果是一样的。我确实RTM但我找不到太多的信息来帮助我解决这个问题。
我哪里做错了?
谢谢您。
编辑:我注意到另一件奇怪的事情了。排队
cur.execute("SELECT * FROM Products WHERE account_id = %d" % acc_id)
,我硬编码了acc\u id值,即成功cur.execute("SELECT * FROM Products WHERE account_id = %d" % 322)
并返回所有行 最佳答案
这实际上并不是一个答案,只是试图从与rbk的聊天中收集所有信息,排除了一堆潜在的问题,但仍然没有给出解释或解决方案,希望其他人能发现问题或想出其他尝试的方法。
很明显是这样的:
cur.execute("SELECT * FROM Products WHERE account_id = %d" % acc_id)
尤其是因为用
322
代替acc_id
可以解决所有问题。(如下所示。)实际上这条线路有两个问题,可能会妨碍它。为了避免sql注入攻击、转义/转换等的正确性和效率,您总是希望使用db-api绑定,而不是字符串格式(以及任何其他语言中的等效格式)。此外,db-abi绑定和字符串格式都需要
tuple
个参数,而不是单个参数。(由于遗留的原因,一个参数通常是有效的,但有时不起作用,然后调试就很混乱了……最好不要这样做。)所以,这应该是: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]
结果是:
10
account id = 333
<type 'long'>
2
当重复运行时,最后一个数字从0到6不等,而第一个总是10。使用
acc_id
和使用333
是没有区别的,但事实确实如此。如果一个查询不知何故“感染”了下一个查询,没有前两行,其余的工作方式相同。因此,使用
acc_id
与使用333
没有区别。然而,事实的确如此。在聊天过程中的某个时刻,我们显然从产品转移到了设备,从322转移到了333,但是无论如何,上面显示的测试绝对是完全按照显示的那样完成的,并且返回了不同的结果。
也许他有一个bug或者mysqldb安装不好的版本。他将尝试寻找一个较新的版本,或者其他python mysql库中的一个,看看它是否有什么不同。
在这一点上,我下一个最好的猜测是,rbk无意中激怒了一些技术娴熟的恶作剧之神,但我甚至想不起其中一个。