You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中PostgreSQL查询返回None,PgAdmin运行正常

问题:调用PostgreSQL查询函数时触发AttributeError错误

问题详情

我编写了Python函数is_paying_user,用于查询PostgreSQL数据库public."Users"表的is_paying字段:

def is_paying_user(user_id: int) -> bool:
    with Database() as cursor:
        res = cursor.execute(f"""SELECT is_paying FROM public."Users" WHERE user_id = {user_id}""")
        return res.fetchone()

自定义的Database上下文管理器定义如下:

class Database:
    def __init__(self):
        self.connection = psycopg2.connect(database="postgres", user=DB_USER, password=DB_PASS,
                                           host=LOCALHOST, port=DB_PORT)

    def __enter__(self):
        return self.connection.cursor()

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.connection.commit()
        self.connection.close()

调用该函数时抛出错误:

AttributeError: 'NoneType' object has no attribute 'fetchone'

使用相同user_id在PgAdmin中执行相同查询可成功,尝试两种参数化查询写法后仍报相同错误:

cursor.execute("""SELECT trackables_amount FROM public."Users" WHERE user_id = %s""", (user_id,))

cursor.execute("""SELECT trackables_amount FROM public."Users" WHERE user_id = %s""", user_id)

解决方法

错误根源

cursor.execute()方法执行SQL后返回值为None,你将这个None赋值给了res,后续调用res.fetchone()自然会触发AttributeError。

修复后的代码

直接使用上下文管理器返回的游标对象调用fetchone(),无需接收execute()的返回值,同时修正参数化查询的正确写法:

def is_paying_user(user_id: int) -> bool:
    with Database() as cursor:
        # 正确的参数化查询,避免SQL注入
        cursor.execute("""SELECT is_paying FROM public."Users" WHERE user_id = %s""", (user_id,))
        result = cursor.fetchone()
        # 处理用户不存在的情况,返回默认值False
        return result[0] if result else False

关键注意点

  • 参数化查询格式:psycopg2要求参数必须是元组类型,因此第二个参数必须写成(user_id,)(末尾的逗号不能省略,否则会被识别为单个值而非元组),你之前的第二种写法直接传user_id是错误的。
  • 空结果处理:如果查询的user_id不存在,fetchone()会返回None,必须添加判断逻辑,避免索引访问报错。
  • 避免SQL注入:永远不要用字符串格式化拼接SQL语句(如最初的f-string写法),这会引入严重的安全漏洞,必须使用参数化查询。

内容的提问来源于stack exchange,提问作者Eliran Turgeman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 21:20:28