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

如何在异步SQLAlchemy中用原生SQL创建并返回模型类实例?

异步SQLAlchemy原生SQL使用问题解答

问题背景

用户现有异步SQLAlchemy代码,希望在使用原生SQL的前提下,让查询返回User类实例(同步版本可通过session.query(User).from_statement(text(query))实现),同时想了解如何用原生SQL创建模型实例。

原异步代码如下:

import asyncio
from sqlalchemy.orm import sessionmaker, declarative_base
from sqlalchemy import text, Column, Integer, String
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession

async_engine = create_async_engine(f'mysql+aiomysql://root:example@127.0.0.1:3306/spy-bot')
AsyncSession = sessionmaker(async_engine, class_=AsyncSession, expire_on_commit=False)

Base = declarative_base()
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(255))

async def main():
    async with AsyncSession() as session:
        stmt = text('SELECT * FROM `users` LIMIT 1')
        result = await session.execute(stmt)
        user = result.one()
        print(type(user), user)

asyncio.run(main())

一、让原生SQL查询返回User类实例

异步SQLAlchemy中,可通过select(User).from_statement()方法实现,替代同步版本的query(User).from_statement()。具体修改如下:

async def main():
    async with AsyncSession() as session:
        # 定义原生SQL语句
        raw_sql = text('SELECT * FROM `users` LIMIT 1')
        # 关联User模型,执行查询
        result = await session.execute(select(User).from_statement(raw_sql))
        # 获取单个实例(对应同步的one())
        user = result.scalar_one()
        print(type(user), user)  # 输出类型为 <class '__main__.User'>

补充说明

  • 如果原生SQL只查询部分字段,需要给text语句明确指定对应模型列,避免字段映射错误:
    raw_sql = text('SELECT id, username FROM `users` LIMIT 1').columns(User.id, User.username)
    result = await session.execute(select(User).from_statement(raw_sql))
    
  • 若需返回多个实例,使用result.scalars().all()替代scalar_one()。

二、用原生SQL创建模型实例

有两种常用方式,根据需求选择:

方式1:执行INSERT后查询返回实例

先执行原生INSERT语句提交,再通过查询获取对应的User实例:

async def create_user(session, username):
    # 原生INSERT语句
    insert_sql = text("INSERT INTO users (username) VALUES (:username)")
    await session.execute(insert_sql, {"username": username})
    await session.commit()
    
    # 查询刚创建的用户实例
    query_result = await session.execute(select(User).where(User.username == username))
    return query_result.scalar_one()

# 在main中调用
async def main():
    async with AsyncSession() as session:
        new_user = await create_user(session, "test_user")
        print(type(new_user), new_user)

方式2:获取自增主键后手动实例化

利用数据库的自增主键返回功能(如MySQL的1073200),拿到主键后直接创建User实例并关联到session:

async def create_user(session, username):
    # 执行INSERT并返回自增ID
    insert_sql = text("INSERT INTO users (username) VALUES (:username); SELECT 1073200 as id")
    result = await session.execute(insert_sql, {"username": username})
    user_id = result.scalar()
    await session.commit()
    
    # 创建User实例并添加到session,使其处于ORM管理状态
    new_user = User(id=user_id, username=username)
    session.add(new_user)
    return new_user

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 11:28:20