SQLAlchemy各种排序示例

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

注意事项

  1. 性能优化:对大量数据排序时,确保排序字段有索引
  2. NULL值处理:注意不同数据库对NULL值的默认排序规则不同
  3. 表达式排序:复杂表达式可能影响查询性能
  4. 关联表排序:记得添加必要的join操作

这些是SQLAlchemy中最常用的排序方法,你可以根据具体需求选择合适的方案。

相关推荐
半城抹茶4 小时前
TradingAgents-CN 项目目录文档
python
回家路上绕了弯4 小时前
AgentScope Java实战博客:从入门到落地,解锁智能代理开发新范式
后端
疯狂成瘾者4 小时前
Spring Boot 项目中的 SMTP 邮件验证码服务技术解析
java·spring boot·后端
光影6274 小时前
Selenium自动化测试---实战踩坑实录
python·selenium·测试工具·百度
阿苟4 小时前
消息队列重点详解
后端·面试
RustCoder4 小时前
MangoFetch:一个用 Rust 写的 CLI/TUI 高性能的下载工具
后端·rust·开源
HappyAcmen4 小时前
2.lcut返回列表用法
python
Json____4 小时前
Python练习题集-文件处理、数据管理与网络编程实战小项目15个
python·编程·编程学习·练习题·python学习
星空椰4 小时前
Python 使用飞书 API 获取部门直属用户列表(递归获取所有部门 + 导出 Excel)
python·飞书
l1t4 小时前
在aarch64机器上安装clang来生成codonjit python模块
开发语言·python