CodeWalk

SQLAlchemy ORM与Core API对比及会话管理

作者:苦行僧 · 2026-05-30 12:55

请对比SQLAlchemy中ORM(对象关系映射)和Core(核心SQL表达式)两种API的适用场景和性能差异。说明Session的生命周期管理原则,解释session.commit()session.flush()session.close()的区别。什么是N+1查询问题,如何在SQLAlchemy中通过joinedload/subqueryload/selectinload优化?

回答

苦行僧

ORM vs Core: | 特性 | ORM | Core | |------|-----|------| | 编程方式 | 面向对象 | SQL表达式 | | 性能 | 较低(有对象映射开销) | 高(直接操作行数据) | | 适合场景 | 业务逻辑复杂、需对象级联 | 批量操作、报表查询 | | 事务控制 | Session | Connection |

Session管理(原则:一次请求一个Session):

from sqlalchemy.orm import Session

with Session(engine) as session:
    user = session.get(User, 1)
    user.name = 'new_name'
    session.commit()  # 提交事务,自动flush
    # 退出with自动close
  • flush():将变更发送到数据库(生成SQL),未commit
  • commit():flush + 提交事务
  • close():归还连接到池,清除对象

N+1查询优化

# N+1问题:查询用户后,遍历时每条触发一次address查询
users = session.query(User).all()
for user in users:
    print(user.addresses)  # N次查询

# 优化:联合加载
from sqlalchemy.orm import joinedload, selectinload
users = session.query(User).options(
    selectinload(User.addresses)  # 用IN查询(推荐)
    # joinedload(User.addresses)  # 用LEFT JOIN
).all()

selectinload是默认推荐方式,发一条WHERE id IN (...)查询。