1. 基础排序
简单单字段排序
python
from sqlalchemy import create_engine, Column, Integer, String, DateTime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
age = Column(Integer)
create_time = Column(DateTime)
# 查询并排序
# 升序
users = session.query(User).order_by(User.age).all()
# 降序
users = session.query(User).order_by(User.age.desc()).all()
# 或者使用负号(仅适用于数字)
users = session.query(User).order_by(-User.age).all()
2. 多字段排序
python
# 先按年龄升序,再按创建时间降序
users = session.query(User)\
.order_by(User.age, User.create_time.desc())\
.all()
# 另一种写法
from sqlalchemy import desc
users = session.query(User)\
.order_by(User.age, desc(User.create_time))\
.all()
3. 使用文本SQL排序
python
from sqlalchemy import text
# 直接使用SQL语句
users = session.query(User)\
.order_by(text("age desc, create_time"))\
.all()
# 带参数的文本排序
users = session.query(User)\
.order_by(text("age :sort_order"), text("name"))\
.params(sort_order='desc')\
.all()
4. 关联表排序
python
class Post(Base):
__tablename__ = 'posts'
id = Column(Integer, primary_key=True)
title = Column(String(100))
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship("User")
# 按关联表的字段排序
posts = session.query(Post)\
.join(Post.user)\
.order_by(User.name.asc(), Post.title)\
.all()
5. 表达式排序
python
from sqlalchemy import func
# 按计算字段排序
users = session.query(User)\
.order_by(func.length(User.name))\
.all()
# 按条件排序(CASE WHEN)
from sqlalchemy import case
users = session.query(User)\
.order_by(
case(
[(User.age < 18, 1), # 未成年人排前面
(User.age >= 60, 2), # 老年人其次
else_=3] # 其他最后
)
)\
.all()
6. NULL值排序
python
# NULLS FIRST / NULLS LAST
from sqlalchemy import nullsfirst, nullslast
# 将NULL值排在最后
users = session.query(User)\
.order_by(nullslast(User.age))\
.all()
# 将NULL值排在最前
users = session.query(User)\
.order_by(nullsfirst(User.age))\
.all()
# 结合升降序
users = session.query(User)\
.order_by(nullslast(User.age.desc()))\
.all()
7. 动态排序
python
def get_users(sort_by='id', sort_order='asc'):
query = session.query(User)
# 根据传入参数动态排序
if sort_order.lower() == 'desc':
query = query.order_by(getattr(User, sort_by).desc())
else:
query = query.order_by(getattr(User, sort_by))
return query.all()
# 使用示例
users = get_users('age', 'desc')
8. 分页排序
python
# 排序后分页
page = 1
page_size = 20
users = session.query(User)\
.order_by(User.create_time.desc())\
.limit(page_size)\
.offset((page - 1) * page_size)\
.all()
9. 完整示例
python
from sqlalchemy import create_and, Column, Integer, String, DateTime, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime
from sqlalchemy import desc, func, text
Base = declarative_base()
class Department(Base):
__tablename__ = 'departments'
id = Column(Integer, primary_key=True)
name = Column(String(50))
employees = relationship("Employee", back_populates="department")
class Employee(Base):
__tablename__ = 'employees'
id = Column(Integer, primary_key=True)
name = Column(String(50))
age = Column(Integer)
salary = Column(Integer)
department_id = Column(Integer, ForeignKey('departments.id'))
hire_date = Column(DateTime, default=datetime.now)
department = relationship("Department", back_populates="employees")
# 复杂排序示例
def complex_sort_example(session):
# 按部门名称、入职时间、工资降序排序
employees = session.query(Employee)\
.join(Employee.department)\
.order_by(
Department.name,
Employee.hire_date.desc(),
Employee.salary.desc()
)\
.all()
# 按工资等级排序
employees = session.query(Employee)\
.order_by(
case(
[(Employee.salary >= 10000, 1), # 高薪
(Employee.salary >= 5000, 2), # 中薪
else_=3] # 低薪
),
Employee.hire_date.desc()
)\
.all()
return employees
注意事项
- 性能优化:对大量数据排序时,确保排序字段有索引
- NULL值处理:注意不同数据库对NULL值的默认排序规则不同
- 表达式排序:复杂表达式可能影响查询性能
- 关联表排序:记得添加必要的join操作
这些是SQLAlchemy中最常用的排序方法,你可以根据具体需求选择合适的方案。