在Python中psycopg2如何检查行是否存在?
def track_exists(self, track_id):
cur = self.conn.cursor()
cur.execute("SELECT fma_track_id FROM tracks WHERE fma_track_id = %s", (track_id,))
if cur.fetchall() > 0:
return true
else:
return false
目前我正在
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "mumu.py", line 38, in track_exists
if cur.fetchall() > 0:
TypeError: 'NoneType' object has no attribute '__getitem__'
答案 0 :(得分:22)
不要使用fetchall()
(返回一个永远不会大于0的列表),使用fetchone()
:
def track_exists(self, track_id):
cur = self.conn.cursor()
cur.execute("SELECT fma_track_id FROM tracks WHERE fma_track_id = %s", (track_id,))
return cur.fetchone() is not None
如果没有要获取的内容, fetchone()
会返回None
,针对is not None
的测试会为您提供一个方便的布尔值来直接返回。
答案 1 :(得分:10)
使用exists
将允许Postgresql在第一次出现时停止搜索,而不是搜索直到用尽:
exists_query = '''
select exists (
select 1
from tracks
where fma_track_id = %s
)'''
cursor.execute (exists_query, (track_id,))
return cursor.fetchone()[0]
另一个优点是它总是返回一个包含布尔值的行,可以直接使用而无需进一步解释。
答案 2 :(得分:2)
您可以使用rowcount
轻松地处理它。这是psycopg文档中关于rowcount
的内容,
此只读属性指定最后一次执行*()产生(对于SELECT等DQL语句)或受影响的(对于UPDATE或INSERT等DML语句)的行数。
如果在光标上没有执行execute*(),或者如果接口无法确定最后一次操作的行数,则该属性为-1。
因此,以下示例将使您更好地了解如何使用rowcount
。
示例-1
>> # if your SELECT query doesn't have any values you'll get 0 as the output
>>> query_1 = 'SELECT * FROM some_table LIMIT 0;'
>>> cursor.execute(query)
>>> cursor.rowcount
0
示例-2
>>> query_2 = 'SELECT * FROM some_table LIMIT 1;'
>>> cursor.execute(query)
>>> cursor.rowcount
1
示例-3
>>> # no LIMIT in the query, so you'll get the whole row count
>>> query_3 = 'SELECT * FROM some_table;'
>>> cursor.execute(query)
>>> cursor.rowcount
14000
示例-4
>>> # this query won't return anything, so you'll get -1 as the rowcount
>>> query_4 = 'CREATE TABLE new_table AS SELECT * FROM old_table;'
>>> cursor.execute(query)
>>> cursor.rowcount
-1
因此您可以按如下所示修改功能,
def track_exists(self, track_id):
cur = self.conn.cursor()
cur.execute("SELECT fma_track_id FROM tracks WHERE fma_track_id = %s", (track_id,))
# if cur.rowcount > 0:
# return True
# else:
# return False
return cur.rowcount > 0 # more Pythonic way
请注意:如果执行UPDATE
查询,您将获得rowcount
的更新行数。因此,基本上rowcount
将显示受查询影响的行数。 CREATE
查询不会影响任何行,因此这就是为什么rowcount
得到-1
的原因。
答案 3 :(得分:-1)
await Task.WhenAll(task1, task2, task3, etc)