Python psycopg2检查行存在

And*_*rdo 11 python sql postgresql psycopg2

在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
Run Code Online (Sandbox Code Playgroud)

目前我正在接受

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__'
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 24

不要使用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
Run Code Online (Sandbox Code Playgroud)

fetchone()None如果没有要获取的内容则返回,并且测试时is not None会为您提供一个方便的布尔值以直接返回.


Clo*_*eto 11

使用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]
Run Code Online (Sandbox Code Playgroud)

另一个优点是它将始终返回包含布尔值的单行,该行可以直接使用而无需进一步解释.


Kus*_*era 7

您可以使用 轻松处理它rowcount。这就是psycopg文档提到的内容rowcount

\n
\n

此只读属性指定最后一个execute*() 生成的行数(对于像SELECT 这样的DQL 语句)或受影响的行数(对于像UPDATE 或INSERT 这样的DML 语句)。

\n

如果没有对游标执行execute*(),则该属性为-1;如果接口无法确定最后一次操作的行数,则该属性为-1。

\n
\n

因此,下面的示例将让您更好地了解如何使用rowcount.

\n
\n

示例 - 1

\n
>> # if your SELECT query doesn\'t have any values you\'ll get 0 as the output\n>>> query_1 = \'SELECT * FROM some_table LIMIT 0;\'\n>>> cursor.execute(query)\n>>> cursor.rowcount\n0\n
Run Code Online (Sandbox Code Playgroud)\n
\n

示例 - 2

\n
>>> query_2 = \'SELECT * FROM some_table LIMIT 1;\'\n>>> cursor.execute(query)\n>>> cursor.rowcount\n1\n
Run Code Online (Sandbox Code Playgroud)\n
\n

示例 - 3

\n
>>> # no LIMIT in the query, so you\'ll get the whole row count\n>>> query_3 = \'SELECT * FROM some_table;\'\n>>> cursor.execute(query)\n>>> cursor.rowcount\n14000\n
Run Code Online (Sandbox Code Playgroud)\n
\n

示例 - 4

\n
>>> # this query won\'t return anything, so you\'ll get -1 as the rowcount\n>>> query_4 = \'CREATE TABLE new_table AS SELECT * FROM old_table;\'\n>>> cursor.execute(query)\n>>> cursor.rowcount\n-1\n
Run Code Online (Sandbox Code Playgroud)\n
\n

所以你可以像下面这样修改你的函数,

\n
def track_exists(self, track_id):\n    cur = self.conn.cursor()\n    cur.execute("SELECT fma_track_id FROM tracks WHERE fma_track_id = %s", (track_id,))\n\n    # if cur.rowcount > 0:\n    #     return True\n    # else:\n    #     return False\n\n    return cur.rowcount > 0  # more Pythonic way\n
Run Code Online (Sandbox Code Playgroud)\n

请注意:如果执行UPDATE查询,您将获得 的更新行数rowcount。所以基本上rowcount会显示有多少行受您的查询影响。CREATE查询不会影响任何行,因此这就是您得到-1for 的原因rowcount

\n