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

使用SQLAlchemy执行原生SQL查询报错,如何获取查询结果?

如何用SQLAlchemy结合原生SQL查询并正确获取输出?

问题代码

import sqlalchemy.pool as pool
import psycopg2
from dotenv import load_dotenv
import os
load_dotenv()


def getconn():
    c = psycopg2.connect(user=os.getenv('POSTGRES_USER'), password = os.getenv('POSTGRES_PASSWORD'),  host=os.getenv('POSTGRES_HOST'), port=os.getenv('DATABASE_PORT'), dbname=os.getenv('POSTGRES_DB'))
    return c


mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5)


def get_connection():
    conn = mypool.connect()
    return conn.cursor()

# use it
db = get_connection()
print(db)
output = db.execute("select 2+2 as sum")
print(output.fetchone())

错误信息

<cursor object at 0x0000021B18795C40; closed: 0>
Traceback (most recent call last):
  File "C:\Users\gourav.kumar\code\genai_ozone_engine\genai_ozone_engine\app\database\database.py", line 25, in <module>
    print(output.fetchone())
AttributeError: 'NoneType' object has no attribute 'fetchone'

问题原因

psycopg2的cursor.execute()方法本身返回None,查询结果直接存储在cursor对象中,并非execute方法的返回值。你将execute的返回值赋值给output,自然得到None,调用fetchone()就会触发错误。

修正方案

方案1:基于现有连接池代码修正

直接使用cursor对象获取结果,同时注意资源回收:

import sqlalchemy.pool as pool
import psycopg2
from dotenv import load_dotenv
import os
load_dotenv()


def getconn():
    c = psycopg2.connect(
        user=os.getenv('POSTGRES_USER'),
        password=os.getenv('POSTGRES_PASSWORD'),
        host=os.getenv('POSTGRES_HOST'),
        port=os.getenv('DATABASE_PORT'),
        dbname=os.getenv('POSTGRES_DB')
    )
    return c


mypool = pool.QueuePool(getconn, max_overflow=10, pool_size=5)


def get_connection():
    conn = mypool.connect()
    return conn, conn.cursor()

# 使用示例
conn, db = get_connection()
try:
    # 执行查询,无需接收返回值
    db.execute("select 2+2 as sum")
    # 直接通过cursor对象获取结果
    result = db.fetchone()
    print(result)  # 输出: (4,)
finally:
    # 关闭cursor并将连接归还到池
    db.close()
    conn.close()

如果需要字典格式的结果,可以修改cursor的创建方式:

# 在get_connection函数中修改cursor创建
return conn, conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
# 此时fetchone()会返回: {'sum': 4}

方案2:使用SQLAlchemy 2.x原生方式执行原生SQL

SQLAlchemy本身提供了更简洁的原生SQL执行方式,无需直接操作psycopg2:

from sqlalchemy import create_engine, text
from dotenv import load_dotenv
import os

load_dotenv()

# 创建SQLAlchemy Engine
engine = create_engine(
    f"postgresql+psycopg2://{os.getenv('POSTGRES_USER')}:{os.getenv('POSTGRES_PASSWORD')}@{os.getenv('POSTGRES_HOST')}:{os.getenv('DATABASE_PORT')}/{os.getenv('POSTGRES_DB')}"
)

# 执行查询
with engine.connect() as conn:
    result = conn.execute(text("select 2+2 as sum"))
    print(result.fetchone())  # 输出: (4,)
    # 若为写操作,需要提交事务
    # conn.commit()

内容的提问来源于stack exchange,提问作者gourav kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:07:37