zoukankan      html  css  js  c++  java
  • 【SQLAlchemy】04-SQLAlchemy高级查询

    好风凭借力,送我上青云。

    1. 排序

    1.1 order_by

    • 正序
    session.query(Article).order_by("-create_time").all()
    
    • 逆序:个人测试无法直接使用-create_time方式,需要导入text
    from sqlalchemy import text
    session.query(Article).order_by(text("-create_time")).all()
    

    1.2 __mapper_args__

    class Article(Base):
    	......
            __mapper_args__ = {
                "order_by": create_time,
                # 倒叙方式一
                "order_by": create_time.desc()
                # 倒叙方式二
                "order_by": text("-create_time")
            }
    

    2. 限制查询

    2.1 limit

    可以限制每次查询的时候只查询几条数据。例如:查询前10条

    session.query(Article).limit(10).all()
    

    2.2 offset

    可以限制查找数据的时候过偏移条。例如:从第10条开始取10条

    session.query(Article).offset(10).limit(10).all()
    

    2.3 slice

    可以对Query对象使用切片操作,来获取想要的数据。例如:获取时间排序的后10条

    session.query(Article).order_by(Article.create_time.desc()).slice(0,10).all()
    
    # 列表切片的方式获取,后缀不需要加all()
    session.query(Article).order_by(Article.create_time.desc())[0:10]
    

    3. 懒加载

    当我们通过外键查询的时候不是直接获取相对应的数据,而是返回一个类似于Query的对象,这样我们就可以继续进行相应的条件过滤。

    那么这时候就可以考虑使lazy='dynamic',其返回的是AppenderQuery对象了,这个对象继承Query因此拥有Query所有的过滤方法

    lazy可用的选项:

    1. select:这个是默认选项。还是拿user.articles的例子来讲。如果你没有访问user.articles这个属性,那么sqlalchemy就不会从数据库中查找文章。一旦你访问了这个属性,那么sqlalchemy就会立马从数据库中查找所有的文章,并把查找出来的数据组装成一个列表返回。这也是懒加载。
    2. dynamic:在访问user.articles的时候返回回来的不是一个列表,而是AppenderQuery对象。
    class Article(Base):
        ......
    
        # 一般懒加载用于一查多,因此定义在反向查询中
        author = relationship("User",backref=backref("articles",lazy="dynamic"))
    

    4. 分组查询、过滤、连接和子查询

    4.1 group_by

    根据某个字段进行分组。比如想要根据性别进行分组,来统计每个分组分别有多少人。

    session.query(User.gender,func.count(User.id)).group_by(User.gender).all()
    
    >>>[('male',2),('female',1)]
    

    4.2 having

    having是对查找结果进一步过滤。比如只想要看未成年人的数量,那么可以首先对年龄进行分组统计人数,然后再对分组进行having过滤。

    session.query(User.age,func.count(User.id)).group_by(User.age).having(User.age >= 18).all()
    

    4.3 join

    join分为left join(左外连接)和right join(右外连接)以及内连接(等值连接)

    比如现在要实现一个功能,要查找所有用户,按照发表文章的数量来进行排序。

    session.query(User,func.count(Article.id)).join(Article).group_by(User.id).order_by(func.count(Article.id).desc()).all()
    

    4.4 subquery

    子查询可以让多个查询变成一个查询,只要查找一次数据库,性能相对来讲更加高效一点

    那么在sqlalchemy中,要实现一个子查询,应该使用以下几个步骤:

    1. 将子查询按照传统的方式写好查询代码,然后在query对象后面执行subquery方法,将这个查询变成一个子查询。
    2. 在子查询中,将以后需要用到的字段通过label方法,取个别名。
    3. 在父查询中,如果想要使用子查询的字段,那么可以通过子查询的返回值上的c属性拿到。
    sq = session.query(User.city.label("city"),User.age.label("age")).filter(User.username=='xxx').subquery()
    
    session.query(User).filter(User.city==sq.c.city,User.age==sq.c.age).all()
    
  • 相关阅读:
    命令拷屏之网络工具
    PHP 设计模式 笔记与总结(1)命名空间 与 类的自动载入
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 计蒜客 1251 仙岛求药
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 蓝桥杯 算法训练 字符串合并
    Java实现 LeetCode 143 重排链表
    Java实现 LeetCode 143 重排链表
  • 原文地址:https://www.cnblogs.com/ydongy/p/13158051.html
Copyright © 2011-2022 走看看