最近个人用python + flask搞了一个小项目,ORM用到的是SQLAlchemy。

    SQLAlchemy的查询方式非常灵活,你所能想像到的复杂SQL 语句,基本上都可以实现。这里简单的总结一下常用的查询技巧。

  1. 多条件组合,可以用and_,or_实现。最外层时,and_可以省略,默认用逗号分开条件。

    db.session.query(User).filter(
    and_(
    or_(User.name==name1,User.name==name2),
    or_(User.status==1,User.status==2)
    ),
    User.active==1
    ).first()
  2. 动态组合条件。针对不同的场景,可能需要不同的查询条件,类似动态的拼接SQL 语句。
            if filter_type == 1:
    search = and_(GameRoom.status ==1,or_(
    and_(GameRoom.white_user_id == user_id,
    GameRoom.active_player == 1),
    and_(GameRoom.black_user_id == user_id,
    GameRoom.active_player == 0)))
    elif filter_type == 2:
    search = and_(GameRoom.status ==1,or_(
    and_(GameRoom.white_user_id == user_id,
    GameRoom.active_player == 0),
    and_(GameRoom.black_user_id == user_id,
    GameRoom.active_player == 1)))
    elif filter_type == 3:
    search = GameRoom.create_by == user_id db.session.query(GameRoom).filter(search).all()
  3. 关联查询。对应SQL的join和left join等。
        session.query(User, Address).filter(User.id == Address.user_id).all()
    session.query(User).join(User.addresses).all()
    session.query(User).outerjoin(User.addresses).all()
  4. 使用别名用aliased,aliased在orm包中。当要对同一个表使用多次关联时,可能需要用到别名。同时,如果查询的结果有多个同名的字段,可以使用label重命名。
    black_user = orm.aliased(User)
    white_user = orm.aliased(User)
    db.session.query(
    GameRoom,
    black_user.score.label("black_score"),
    white_user.score.label("white_score")
    ).outerjoin(black_user,GameRoom.black_user_id==black_user.user_id).outerjoin(
    white_user,GameRoom.white_user_id==white_user.user_id).filter(
    GameRoom.id==room_id
    ).all()
  5. 聚合查询和使用数据库函数。func可以调用各种聚合函数,和当前数据库支持的其它函数。
    session.query(User.name, func.count('*').label("user_count")).group_by(User.name).all()
    
    session.query(User.name, func.sum(User.id).label("user_id_sum")).filter(func.to_days(User.create_date)==func.to_days(func.now())).group_by(User.name).all()
  6. 子查询。 

    stmt = db.session.query(Address.user_id, func.count('*').label("address_count")).group_by(Address.user_id).subquery()
    db.session.query(User, stmt.c.address_count).outerjoin((stmt, User.id == stmt.c.user_id)).order_by(User.id).all()
  7. 直接运行SQL语句查询。如果查询实在太复杂,觉得用SQLAlchemy查询方式很难实现,或者要通过存储过程实现查询,可以让SQLAlchemy直接运行SQL语句返回结果。
            sql ="""select b.user_id,b.user_name,b.icon,b.score,a.add_score from
    (select user_id, sum(score_new - score_old) as add_score from user_score_log
    where year(create_date)=year(now()) and month(create_date)=month(now())
    group by user_id) a join users b on a.user_id=b.user_id
    order by a.add_score desc limit 50"""
    list_top = db.session.execute(sql).fetchall()
  8. 分页查询。sqlalchemy中分页用到pagination,先不说性能怎么样,使用起来是真的非常方便。
            pagination = GameMessage.query.filter(GameMessage.game_id==game_id).\
    order_by(GameMessage.id.desc()).\
    paginate(page, per_page=20, error_out=True)
    pages = pagination.pages
    total = pagination.total
    items = pagination.items

  总的来说,SQLAlchemy是我用过的最好的ORM 框架之一(其实我最熟的是.net,python也只用过这一个ORM工具)。基本上常见的SQL 语句,这里都已经实现。如果你的查询实在太复杂的,可能需要用存储过程来实现,直接运行SQL也不失为一种简便的方法。

SQLAlchemy复杂查询的更多相关文章

  1. pythonのsqlalchemy简单查询

    #!/usr/bin/env python import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.dec ...

  2. flask 中orm关系映射 sqlalchemy的查询

    flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询   一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课 ...

  3. 【Flask】Sqlalchemy 子查询

    ### subquery:子查询可以让多个查询变成一个查询,只要查找一次数据库,性能相对来讲更加高效一点.不用写多个sql语句就可以实现一些复杂的查询.那么在sqlalchemy中,要实现一个子查询, ...

  4. SQLAlchemy的查询操作Query

    查询操作 查询子句使用session的.query()方法来获取Query查询对象.查询对象能够使用一些方法来对应一些查询子句,比如.order_by(),.limit(),.filter()等. 查 ...

  5. SQLAlchemy -高级查询

    查询 # -*- coding: utf-8 -*-   from sqlalchemy.orm import sessionmaker   from SQLAlchemy.create import ...

  6. day95:flask:SQLAlchemy数据库查询进阶&关联查询

    目录 1.数据库查询-进阶 1.常用的SQLAlchemy查询过滤器 2.常用的SQLAlchemy查询结果的方法 3.filter 4.order_by 5.count 6.limit&of ...

  7. Python自动化之sqlalchemy关联查询

    外键关联 from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship class Address(Base): ...

  8. 【SQLAlchemy】SQLAlchemy修改查询字段列名

    SQLAlchemy问题记录 company price quantity Microsoft Google Google Google 要实现脚本 select price, sum(quantit ...

  9. SQLAlchemy 在查询期间丢失与MySQL服务器的连接

    遇到问题 pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query') 建立的 pymysq ...

随机推荐

  1. 修改NSMutableArray中的元素时的注意事项

    最近做项目遇到从文件加载数组,并对数组中的元素进行操作的问题,特意写了个Demo,记录下要注意的东西: 代码如下: NSArray *array = @["]; NSMutableArray ...

  2. NOIP2017SummerTraining0720

    这套题,看到第一题就想到了以前做过的运动鞋那道题,然后就往DP这个方向去思考,想来想去每什么思路,然后就去看第二题,第二题一看就是一道最短路的问题,但是它的建图十分困难, 怎么打都不知到该怎么建图,然 ...

  3. 移动WEB 响应式设计 @media总结

    第一种: 在引用样式的时候添加 <link rel="stylesheet" media="mediatype and|not|only (media featur ...

  4. Linux用户和文件权限管理

    本文为原创文章,转载请标明出处 目录 用户管理 系统用户文件 添加用户 useradd 设置用户密码 passwd 删除用户 userdel 用户管理 usermod 用户组管理 系统用户组文件 添加 ...

  5. ZOJ2965 Accurately Say "CocaCola"! 线性扫描

    Accurately Say "CocaCola"! 范围找到:1--700左右,然后打表就ok了 #include<cstdio> #include<cstdl ...

  6. Java API 常用类(一)

    Java API 常用类 super类详解 "super"关键字代表父类对象.通过使用super关键字,可以访问父类的属性或方法,也可以在子类构造方法中调用父类的构造方法,以便初始 ...

  7. OC实现同步访问属性

    有时候,我们在开发过程中需要对属性的访问进行同步操作,这种属性需要做成原子的,用atomic来修饰属性,即可实现这一点. 如果我们想自己实现,可以按照下面方式写代码: SFPerson.h #impo ...

  8. live555_RTSP连接建立以及请求消息处理过程

    1,RTSP连接的建立过程    RTSPServer类用于构建一个RTSP服务器,该类同时在其内部定义了一个RTSPClientSession类,用于处理单独的客户会话.    首先创建RTSP服务 ...

  9. 【转载】兼容所有浏览器的JQuery zClip插件实现复制到剪贴板功能

    文章转载自 代码家园 http://www.daimajiayuan.com/ 原文链接:http://www.daimajiayuan.com/sitejs-17973-1.html原文摘要: 相信 ...

  10. Selenium 设置浏览器下载 Firefox 和Chrome

    当我们在使用Selenium运行自动化测试时,偶尔需要用到下载功能,但浏览器的下载可能会弹出下载窗口,或者下载路径不是我们想要保存的位置,所以在通过Selenium启动浏览器时需要做相关的设置,将使这 ...