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

如何在SQLAlchemy插入数据后返回Base类对象?

解决SQLAlchemy异步插入后返回对应模型对象的问题

正确实现方式(异步场景)

你用的是SQLAlchemy 1.4异步模式+asyncpg,要插入后返回完整的EdaToken对象,推荐用ORM标准流程:session.add() + commit() + refresh(),确保拿到数据库自动生成的字段(比如自增id)。

示例代码:

from sqlalchemy.ext.asyncio import AsyncSession
from your_module import EdaToken

async def create_eda_token(db: AsyncSession, token_data: dict) -> EdaToken:
    # 每次插入都创建新的模型实例
    new_token = EdaToken(**token_data)
    db.add(new_token)
    await db.commit()
    # 刷新对象,同步数据库端生成的字段值
    await db.refresh(new_token)
    return new_token

两种错误写法的问题分析

第一种:报错'CursorResult' object has no attribute 'id'

这种情况是直接用了SQLAlchemy Core层的execute()插入,没有转换为ORM对象。比如错误代码类似:

result = await db.execute(insert(EdaToken).values(**token_data))
return result.id  # CursorResult是Core执行结果,不是EdaToken实例

如果坚持用Core方式,需要结合returning()子句获取完整对象:

result = await db.execute(insert(EdaToken).values(**token_data).returning(EdaToken))
new_token = result.scalar_one()
return new_token

但还是更推荐ORM的add()+refresh()写法,更贴合ORM设计逻辑。

第二种:仅能插入一次,后续返回旧对象

核心问题是重复复用了同一个模型实例。比如错误代码把实例定义在函数外部:

# 错误示例:全局实例导致重复插入失效
new_token = EdaToken()

async def create_eda_token(db: AsyncSession, token_data: dict):
    new_token.__dict__.update(token_data)
    db.add(new_token)
    await db.commit()
    return new_token

第一次插入后,该实例已被会话标记为持久化状态,后续修改再添加会被SQLAlchemy判定为更新操作,不会生成新记录,自然返回旧对象。解决办法就是每次插入都在函数内部创建新的EdaToken实例。

额外注意点

  • 确保EdaToken的主键字段(比如id)配置了自增:
from sqlalchemy import Column, Integer
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class EdaToken(Base):
    __tablename__ = 'eda_token'
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 其他业务字段...
  • 异步操作必须全程用await执行数据库方法(commit、refresh、execute等),不能遗漏异步关键字。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:15:35