SQLAlchemy 和 Peewee 的功能和使用方面的对比

SQLAlchemy 和 Peewee 的功能和使用方面的对比

SQLAlchemy vs Peewee 对比

基本特性对比

特性 SQLAlchemy Peewee
复杂度 功能丰富,学习曲线陡峭 轻量级,简单易学
灵活性 极高,支持复杂查询 适中,满足常见需求
性能 优秀,但有额外开销 更轻量,性能更好
文档 非常完善 简洁明了
社区支持 最大,生态丰富 较小但活跃

安装和基本设置

SQLAlchemy

pip install sqlalchemy
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
engine = create_engine('sqlite:///example.db')
Session = sessionmaker(bind=engine)
session = Session()

Peewee

pip install peewee
from peewee import *

db = SqliteDatabase('my_app.db')
# 或者 PostgreSQL: db = PostgresqlDatabase('my_db')
# 或者 MySQL: db = MySQLDatabase('my_db')

模型定义对比

SQLAlchemy

class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    username = Column(String(50), unique=True)
    email = Column(String(100))
    age = Column(Integer)
    is_active = Column(Boolean, default=True)
    
    def __repr__(self):
        return f"<User(username='{self.username}')>"

# 创建表
Base.metadata.create_all(engine)

Peewee

class User(Model):
    username = CharField(unique=True, max_length=50)
    email = CharField(max_length=100)
    age = IntegerField()
    is_active = BooleanField(default=True)
    
    class Meta:
        database = db
        
    def __str__(self):
        return self.username

# 创建表
db.create_tables([User])

基本 CRUD 操作对比

创建数据

SQLAlchemy

# 方法1:实例化后添加
user = User(username='john', email='john@example.com', age=25)
session.add(user)
session.commit()

# 方法2:批量创建
session.bulk_insert_mappings(User, [
    {'username': 'alice', 'email': 'alice@example.com', 'age': 30},
    {'username': 'bob', 'email': 'bob@example.com', 'age': 35}
])
session.commit()

Peewee

# 方法1:create()
user = User.create(username='john', email='john@example.com', age=25)

# 方法2:save()
user = User(username='john', email='john@example.com', age=25)
user.save()

# 方法3:批量插入
User.insert_many([
    {'username': 'alice', 'email': 'alice@example.com', 'age': 30},
    {'username': 'bob', 'email': 'bob@example.com', 'age': 35}
]).execute()

查询数据

SQLAlchemy

# 基本查询
users = session.query(User).all()
user = session.query(User).filter(User.id == 1).first()
user = session.query(User).get(1)  # 主键查询

# 复杂查询
active_users = session.query(User).filter(User.is_active == True).all()
young_users = session.query(User).filter(User.age < 30).all()

# 排序和限制
recent_users = session.query(User).order_by(User.id.desc()).limit(10).all()

# 聚合查询
from sqlalchemy import func
user_count = session.query(func.count(User.id)).scalar()
avg_age = session.query(func.avg(User.age)).scalar()

Peewee

# 基本查询
users = User.select()
user = User.get(User.id == 1)
user = User.get_by_id(1)  # 主键查询

# 复杂查询
active_users = User.select().where(User.is_active == True)
young_users = User.select().where(User.age < 30)

# 排序和限制
recent_users = User.select().order_by(User.id.desc()).limit(10)

# 聚合查询
user_count = User.select(fn.COUNT(User.id)).scalar()
avg_age = User.select(fn.AVG(User.age)).scalar()

更新数据

SQLAlchemy

# 更新单个对象
user = session.query(User).get(1)
user.email = 'newemail@example.com'
session.commit()

# 批量更新
session.query(User).filter(User.age < 18).update({
    User.is_active: False
})
session.commit()

Peewee

# 更新单个对象
user = User.get(User.id == 1)
user.email = 'newemail@example.com'
user.save()

# 批量更新
User.update(is_active=False).where(User.age < 18).execute()

删除数据

SQLAlchemy

# 删除单个对象
user = session.query(User).get(1)
session.delete(user)
session.commit()

# 批量删除
session.query(User).filter(User.age < 18).delete()
session.commit()

Peewee

# 删除单个对象
user = User.get(User.id == 1)
user.delete_instance()

# 批量删除
User.delete().where(User.age < 18).execute()

高级功能对比

关系映射

SQLAlchemy

from sqlalchemy.orm import relationship
from sqlalchemy import ForeignKey

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(50))
    
    # 一对多关系
    posts = relationship("Post", back_populates="author")
    # 多对多关系
    roles = relationship("Role", secondary="user_roles")

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

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

class UserRole(Base):
    __tablename__ = 'user_roles'
    user_id = Column(Integer, ForeignKey('users.id'), primary_key=True)
    role_id = Column(Integer, ForeignKey('roles.id'), primary_key=True)

Peewee

class User(Model):
    username = CharField()
    class Meta:
        database = db

class Post(Model):
    title = CharField()
    author = ForeignKeyField(User, backref='posts')
    class Meta:
        database = db

class Role(Model):
    name = CharField()
    users = ManyToManyField(User, backref='roles')
    class Meta:
        database = db

UserRole = Role.users.get_through_model()

复杂查询

SQLAlchemy

from sqlalchemy import and_, or_, not_, func

# 复杂条件查询
users = session.query(User).filter(
    and_(
        User.age >= 18,
        or_(User.username.like('%admin%'), User.email.like('%company%')),
        not_(User.is_active == False)
    )
).all()

# 子查询
subquery = session.query(func.avg(User.age)).scalar_subquery()
older_users = session.query(User).filter(User.age > subquery).all()

# 连接查询
result = session.query(User, Post).join(Post).all()

Peewee

# 复杂条件查询
users = User.select().where(
    (User.age >= 18) &
    ((User.username.contains('admin')) | (User.email.contains('company'))) &
    (User.is_active == True)
)

# 子查询
avg_age = User.select(fn.AVG(User.age)).scalar()
older_users = User.select().where(User.age > avg_age)

# 连接查询
result = User.select(User, Post).join(Post, JOIN.LEFT_OUTER).execute()

事务处理

SQLAlchemy

try:
    # 开始事务
    user = User(username='test')
    session.add(user)
    session.flush()  # 获取自增ID但不提交
    
    post = Post(title='Test Post', user_id=user.id)
    session.add(post)
    
    session.commit()  # 提交事务
except Exception as e:
    session.rollback()  # 回滚事务
    raise

Peewee

with db.atomic():  # 自动事务管理
    user = User.create(username='test')
    post = Post.create(title='Test Post', author=user)

# 手动事务
with db.transaction():
    try:
        user = User.create(username='test')
        post = Post.create(title='Test Post', author=user)
    except Exception as e:
        db.rollback()
        raise

性能优化

SQLAlchemy

# 预加载关联数据
users = session.query(User).options(joinedload(User.posts)).all()

# 批量查询优化
session.query(User).yield_per(1000)  # 分批获取

# 原生SQL
result = session.execute("SELECT * FROM users WHERE age > :age", {"age": 18})

Peewee

# 预加载关联数据
users = User.select().prefetch(Post)

# 批量查询
for user in User.select().iterator():
    print(user.username)

# 原生SQL
cursor = db.execute_sql("SELECT * FROM users WHERE age > %s", [18])

使用场景建议

选择 SQLAlchemy 的情况:

  • 大型复杂项目
  • 需要复杂的数据库操作
  • 团队熟悉 SQLAlchemy
  • 需要数据库无关性
  • 企业级应用

选择 Peewee 的情况:

  • 中小型项目
  • 快速原型开发
  • 学习 ORM 概念
  • 对性能要求较高
  • 喜欢简洁的 API

总结

SQLAlchemy 适合需要强大功能和灵活性的项目,但学习成本较高;Peewee 则更适合快速开发和中小型项目,API 更加直观易用。选择哪个主要取决于项目的复杂度和团队的技术栈。

posted @ 2025-07-28 11:03  zart2007  阅读(268)  评论(0)    收藏  举报