排序

session.query(模型).order_by(字段).all()

  • 默认排序顺序 升序 asc
  • 降序 desc()

1.order_by:可以指定根据这个表中的某个字段进行排序,如果在前面加了⼀
个-,代表的是降序排序。

2.在模型定义的时候指定默认排序:有些时候,不想每次在查询的时候都指定排
序的方式,可以在定义模型的时候就指定排序的方式。
__mapper_args__

  1. class Article(Base):
  2. __tablename__ = 'article'
  3. id = Column(Integer, primary_key=True, autoincrement=True)
  4. title = Column(String(50))
  5. # create_time = Column()
  6. def __str__(self):
  7. return "Article(title:%s)" % self.title
  8. __mapper_args__ = {
  9. "order_by": id.desc()
  10. # "order_by": id
  11. }

limit

可以限制每次查询的时候只查询几条数据

  1. # 前三条数据
  2. articles = session.query(Article).limit(3).all()

offset

可以限制查找数据的时候过滤掉前面多少条。

  1. articles = session.query(Article).offset(2).limit(3)

切片

效率没有offset+limit高,因为切片是先从数据库先查询出所有,然后再进行切片,offset+limit
是在数据库中构造limit语句,先偏移然后只查询需要的数据条数

  1. articles = session.query(Article).all()[2:5]

分组

准备模型类和数据

  1. class User(Base):
  2. __tablename__ = "users"
  3. id = Column(Integer, primary_key=True, autoincrement=True)
  4. username = Column(String(50), nullable=False)
  5. gender = Column(Enum('男', '女'))
  6. age = Column(Integer)
  7. Base.metadata.drop_all()
  8. Base.metadata.create_all()
  9. session = sessionmaker(bind=engine)()
  10. import random
  11. for x in range(10):
  12. user = User(username='juran%s' % x, gender=random.choice(['男', '女']), age=random.randint(12, 26))
  13. session.add(user)
  14. session.commit()

image.png

group_by

  1. # 按照性别来进行分组, 求男女的人数
  2. # 聚合函数 一般会和分组进行使用
  3. from sqlalchemy import func
  4. result = session.query(User.gender, func.count(User.id)).group_by(User.gender).all()
  5. # SELECT gender FROM users GROUP BY users.gender
  6. print(result) # [('男', 6), ('女', 4)]

having

  1. from sqlalchemy import func
  2. result = session.query(User.age, func.count(User.id)).group_by(User.age).having(User.age < 18).all()
  3. # SELECT users.age , count(users.id) FROM users GROUP BY users.age HAVING users.age < 8
  4. print(result) # [(17, 1), (14, 2), (13, 1)]

子查询

不推荐,语法(select ……) 作为一个整体,效率和两次SQL差不多,但语法更复杂

准备模型类和数据

  1. class User(Base):
  2. __tablename__ = "users"
  3. id = Column(Integer, primary_key=True, autoincrement=True)
  4. username = Column(String(50), nullable=False)
  5. city = Column(String(50))
  6. age = Column(Integer)
  7. def __str__(self):
  8. return "User(username:%s)" % self.username

image.png

  1. # 查询和ecithy 相同的城市和年龄的人
  2. # user = session.query(User).filter(User.username == 'ecithy').first()
  3. result = session.query(User.username).filter(User.city == user.city, User.age == user.age).all()
  4. # SELECT users.username FROM users WHERE users.city = '北京' and users.age = 18
  5. for data in result:
  6. print(data)
  7. sub = session.query(User.city.label('city'), User.age.label('age')).filter(User.username == 'ecithy').subquery()
  8. # c column
  9. result = session.query(User).filter(User.city == sub.c.city, User.age == sub.c.age).all()
  10. for data in result:
  11. print(data)

join⽅法

作用:把两张表字段相等的数据连接成一张表
join查询分为两种,⼀种是inner join,另⼀种是outer join。默认的是inner
join,如果指定left join或者是right join则为outer join。如果想要查询User及
其对应的Address,则可以通过以下方式来实现

  1. session.query(User,Address).filter(User.id==Address.user_id).all():

总结

子查询和join查询具体选择哪个,需要根据实际情况看两张表的数据大小和SQL语句查询的具体需求。一般推荐join效率更高。