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 更加直观易用。选择哪个主要取决于项目的复杂度和团队的技术栈。
浙公网安备 33010602011771号