我使用SELECT COUNT(*) FROM db WHERE <expression>
查看一组记录是否为空。所以:
>>> cnt = c.fetchone()
>>> print cnt
(0L,)
我的问题是:你如何测试这种情况?
我还有很多其他方法可以实现这一目标。有类似以下内容吗?
if cnt==(0L,):
# do something
答案 0 :(得分:2)
fetchone
返回一行,这是一系列列。
如果您想获得序列中的第一个值,请使用[0]
。
您可以将行与(0,)
进行比较,正如您所建议的那样。但据我所知,一般的DB-API和特定的MySQLdb库都不能保证行的序列 kind ;它可以是列表,也可以是自定义序列类。因此,依赖它是一个元组的事实可能不是一个好主意。而且,既然不这么容易,为什么不安全又便携?
所以:
count_row = c.fetchone()
count = count_row[0]
if count == 0:
do_something()
或者,将它们放在一行:
if c.fetchone()[0] == 0:
do_something()
答案 1 :(得分:0)
谢谢。你的第一个序列有效,不知道我怎么没试过那个,但我没有。第二种结构出错:...对象没有属性“ getitem ”。我猜我的MySQLdb版本(1.2.3_4,Python 2.7)不支持它。
我在过渡期间所做的是通过执行构造为返回零记录的count(*)来构造零元组。这似乎工作正常
答案 2 :(得分:0)
使用游标对象的.rowcount
属性来检查结果集中是否有任何行通常更容易。此属性为specified in the Python Database API:
此只读属性指定最后一行的行数 生成.execute*()(对于
SELECT
等DQL语句) 受影响(适用于UPDATE
或INSERT
等DML语句。 [9]如果未执行.execute*(),则属性为-1 最后一次操作的游标或行数是不可能的 由界面决定。 [7]
.rowcount
时请注意,根据上述规范,当前一个语句产生或影响的行数“无法由接口确定”时,Cursor.rowcount
应设置为-1
。使用SSCursor
和SSDictCursor
游标类时会发生这种情况。
原因是MySQL C API有两个不同的函数用于检索结果集:mysql_store_result()
和mysql_use_result()
。区别在于mysql_use_result()
在您要求时从结果集中读取行,而不是在执行查询时立即存储整个结果集。对于非常大的结果集,这种“无缓冲”方法可以更快,并且在客户端机器上使用更少的内存;但是,它使接口无法确定执行查询时结果集包含多少行。
SSCursor
和SSDictCursor
都会调用mysql_use_result()
,因此无论结果集的大小如何,其.rowcount
属性都应保留值-1
。相反,DictCursor
和默认的Cursor
类调用mysql_store_result()
,它在执行查询后立即读取并计算整个结果集。
更糟糕的是,.rowcount
属性在首次打开游标时只保留值-1
;执行查询后,它会收到mysql_affected_rows()
的返回值。问题是mysql_affected_rows()
返回一个无符号长整数,它以can be very counterintuitive的方式表示值-1
,并且不会被像cursor.rowcount == -1
这样的条件捕获。
如果你正在做的只事情正在计算记录,那么.rowcount
就不那么有用,因为你的COUNT(*)
查询将返回一行是否记录存在与否。在这种情况下,以与从查询中获取结果时测试任何值相同的方式测试零值。是否可以执行c.fetchone()[0] == 0
取决于您正在使用的游标类;它适用于Cursor
或SSCursor
,但DictCursor
或SSDictCursor
无法获取字典而不是元组。
重要的是在代码中明确发生了什么,这就是为什么我建议不要使用c.fetchone() == (0,)
。当您需要做的就是测试单个值时,测试整行;在测试之前从行中获取值,您的代码将更加清晰。就个人而言,我发现c.fetchone()[0]
是不必要的不透明;我更喜欢:
row = cursor.fetchone()
if row[0] == 0:
do_something()
这使得它非常清晰,而不是太详细,你正在测试行的第一项。当我做一些比简单的COUNT()
或EXISTS()
更复杂的事情时,我更喜欢使用DictCursor
,以便我的代码依赖于(最多)显式别名,而不依赖于隐式列排序
另一方面,如果你真的需要获取结果集并且计数纯粹是偶然的,只要你没有使用其中一个无缓冲的游标类,你就可以执行重要的查询而不用担心COUNT()
:
cursor.execute(r"SELECT id, name, email FROM user WHERE date_verified IS NULL;")
if cursor.rowcount == 0:
print 'No results'