SQLAlchemy 是 Python 中最流行的 ORM(对象关系映射)框架之一,它提供了完整的企业级持久化模式,旨在高效和高性能地访问数据库。

核心组件

1. Engine(引擎)

Engine 是 SQLAlchemy 的核心接口,负责数据库连接管理和 SQL 语句的执行。

from sqlalchemy import create_engine

# 创建引擎
engine = create_engine('sqlite:///example.db', echo=True)
# 其他数据库连接示例:
# PostgreSQL: postgresql://user:password@localhost/mydatabase
# MySQL: mysql+pymysql://user:password@localhost/mydatabase

2. ORM(对象关系映射)

声明基类

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

定义模型

from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.sql import func

class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    name = Column(String(50), nullable=False)
    email = Column(String(100), unique=True)
    created_at = Column(DateTime, default=func.now())
    
    def __repr__(self):
        return f"<User(name='{self.name}', email='{self.email}')>"

3. Session(会话)

Session 用于管理所有数据库操作。

from sqlalchemy.orm import sessionmaker

# 创建会话工厂
Session = sessionmaker(bind=engine)
session = Session()

基本操作

创建表

Base.metadata.create_all(engine)

CRUD 操作

# 创建
new_user = User(name='John Doe', email='john@example.com')
session.add(new_user)
session.commit()

# 查询
users = session.query(User).all()
user = session.query(User).filter_by(name='John Doe').first()

# 更新
user.email = 'new_email@example.com'
session.commit()

# 删除
session.delete(user)
session.commit()

查询 API

基本查询

# 获取所有记录
session.query(User).all()

# 获取第一条记录
session.query(User).first()

# 按条件过滤
session.query(User).filter(User.name == 'John Doe').all()
session.query(User).filter_by(name='John Doe').all()

# 限制结果数量
session.query(User).limit(5).all()

# 排序
session.query(User).order_by(User.name.desc()).all()

高级查询

from sqlalchemy import and_, or_

# 多条件查询
session.query(User).filter(
    and_(User.name == 'John Doe', User.email.like('%example.com'))
).all()

# 或条件
session.query(User).filter(
    or_(User.name == 'John Doe', User.name == 'Jane Doe')
).all()

# 聚合函数
from sqlalchemy import func
session.query(func.count(User.id)).scalar()

关系映射

一对多关系

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

class Post(Base):
    __tablename__ = 'posts'
    
    id = Column(Integer, primary_key=True)
    title = Column(String(100))
    content = Column(String(1000))
    user_id = Column(Integer, ForeignKey('users.id'))
    
    # 定义关系
    author = relationship("User", back_populates="posts")

# 在 User 类中添加反向引用
User.posts = relationship("Post", order_by=Post.id, back_populates="author")

多对多关系

# 关联表
post_tags = Table('post_tags', Base.metadata,
    Column('post_id', Integer, ForeignKey('posts.id')),
    Column('tag_id', Integer, ForeignKey('tags.id'))
)

class Tag(Base):
    __tablename__ = 'tags'
    
    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    
    posts = relationship("Post", secondary=post_tags, back_populates="tags")

# 在 Post 类中添加
Post.tags = relationship("Tag", secondary=post_tags, back_populates="posts")

事务管理

# 自动提交
try:
    user = User(name='Test User')
    session.add(user)
    session.commit()
except:
    session.rollback()
    raise
finally:
    session.close()

# 使用上下文管理器
with session.begin():
    user = User(name='Test User')
    session.add(user)

连接池配置

from sqlalchemy import create_engine
from sqlalchemy.pool import QueuePool

engine = create_engine(
    'postgresql://user:password@localhost/mydatabase',
    poolclass=QueuePool,
    pool_size=5,
    max_overflow=10,
    pool_timeout=30,
    pool_recycle=1800
)

性能优化技巧

1. 批量操作

# 批量插入
session.bulk_save_objects([
    User(name=f'User {i}', email=f'user{i}@example.com')
    for i in range(1000)
])
session.commit()

2. 延迟加载与急加载

# 延迟加载(默认)
user = session.query(User).first()
posts = user.posts  # 此时才执行查询

# 急加载
from sqlalchemy.orm import joinedload
user = session.query(User).options(joinedload(User.posts)).first()
posts = user.posts  # 已经预先加载

3. 使用 Core 进行高性能操作

from sqlalchemy import insert, update, delete

# 使用 Core 进行批量插入
stmt = insert(User).values([
    {'name': f'User {i}', 'email': f'user{i}@example.com'}
    for i in range(1000)
])
engine.execute(stmt)

最佳实践

  1. 会话管理: 为每个请求创建新的会话,请求结束后关闭
  2. 错误处理: 总是使用 try-except 块处理数据库操作
  3. 性能监控: 使用 echo=True 在开发时查看生成的 SQL
  4. 连接池: 在生产环境中合理配置连接池参数
  5. 迁移工具: 使用 Alembic 进行数据库迁移管理

总结

SQLAlchemy 提供了强大而灵活的数据库操作能力,从简单的 ORM 操作到复杂的原生 SQL 查询都能胜任。通过合理使用其各种特性,可以构建出既高效又易于维护的数据库应用。

建议在实际项目中结合 Alembic(数据库迁移工具)和适当的连接池配置,以获得最佳的性能和可维护性。