我正在尝试使用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无意中激怒了一些技术娴熟的恶作剧之神,但我甚至想不起其中一个。

10-04 22:22