全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-19 9 分钟 ✍️ juanwangdev

ORM框架原理

ORM(Object-Relational Mapping)将关系数据库映射为对象模型,消除 SQL 与面向对象编程的阻抗失配。

核心概念

对象关系映射

Python
数据库表 ←→ Python 类
表字段   ←→ 类属性
表记录   ←→ 类实例
外键关系 ←→ 对象引用

映射示例

Python
# 数据库表
CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(100)
);

# ORM 映射
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    email = Column(String(100))

核心实现机制

1. 元数据映射

Python
# SQLAlchemy 示例
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

# 元数据存储表结构信息
print(User.__table__)  # Table对象

2. 工作单元模式(Unit of Work)

Python
# Django ORM 示例
user = User.objects.get(id=1)  # 查询
user.name = 'New Name'         # 修改(未写入数据库)
user.save()                    # 提交到数据库

# SQLAlchemy Session
session = Session()
user = session.query(User).get(1)
user.name = 'New Name'
session.commit()  # 批量提交所有变更

3. 延迟加载(Lazy Loading)

Python
# 关联对象延迟加载
user = session.query(User).first()
# 此时未加载 posts

posts = user.posts  # 访问时才执行查询

4. 查询构建器

Python
# SQLAlchemy 查询构建
query = session.query(User).filter(User.age > 18).order_by(User.name)

# 等价 SQL
# SELECT * FROM users WHERE age > 18 ORDER BY name

# Django ORM
User.objects.filter(age__gt=18).order_by('name')

关系映射

一对多

Python
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    posts = relationship('Post', back_populates='user')

class Post(Base):
    __tablename__ = 'posts'
    id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('users.id'))
    user = relationship('User', back_populates='posts')

多对多

Python
# 需要中间表
student_course = Table(
    'student_course', Base.metadata,
    Column('student_id', Integer, ForeignKey('students.id')),
    Column('course_id', Integer, ForeignKey('courses.id'))
)

class Student(Base):
    __tablename__ = 'students'
    id = Column(Integer, primary_key=True)
    courses = relationship('Course', secondary=student_course, back_populates='students')

class Course(Base):
    __tablename__ = 'courses'
    id = Column(Integer, primary_key=True)
    students = relationship('Student', secondary=student_course, back_populates='courses')

N+1 查询问题

问题示例

Python
# N+1 问题
users = session.query(User).all()  # 1 次查询
for user in users:
    print(user.posts)  # N 次查询(每个 user 都查询一次 posts)

解决方案:预加载

text
# joinedload - JOIN 查询
users = session.query(User).options(joinedload(User.posts)).all()

# selectinload - IN 查询
users = session.query(User).options(selectinload(User.posts)).all()

# Django prefetch_related
User.objects.prefetch_related('posts')

主流 ORM 框架对比

特性Django ORMSQLAlchemyPeewee
学习曲线中高
灵活性
性能控制
复杂查询
数据库支持多种多种多种
独立使用不推荐推荐推荐

Django ORM 适合 Django 项目,SQLAlchemy 适合独立项目或复杂场景。

要点总结

  1. ORM 核心是将表映射为类、记录映射为实例
  2. 工作单元模式批量管理对象状态变更
  3. 延迟加载提升性能,但需警惕 N+1 问题
  4. 复杂查询可回退到原生 SQL
  5. SQLAlchemy 灵活性最高,Django ORM 最易上手

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python DevOps与自动化
下一篇 → Python依赖管理工具
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库