• 【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()
    
  • 相关阅读:
    C# 类 根据属性名称取属性值
    WebService WCF 契约的解释
    NHibenate xml 数据库配置 说明
    使Spring.NET的IOC容器支持动态加载的程序集
    知识点滴:持久层,DAO,API,DAL,BLL,DLL,csproj,sln
    spring.net nhibernate 分布布式事务(下)
    简明教程 C# Webservice实例
    C# 中 以 &# 打头的 编码 是: html 编码解码地址 转换
    spring.net 结合简单三层实例
    关于行号输出的简单命令
  • 原文地址:https://www.cnblogs.com/ydongy/p/13158051.html
Copyright © 2020-2023  润新知