最近个人用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. go-fasthttp源码分析

    1.架构 listener->server->workerpool 1.1.workerpool中有两种缓存: a.wp.ready,缓存未退出worker, b.worker退出后用sy ...

  2. AngularJS小结

    1.简介 AngularJS 通过 ng-directives 扩展了 HTML. 2.AngularJS指令 ng-app 指令定义一个AngularJS 应用程序的根元素.指令在网页加载完毕时会自 ...

  3. MXNet--DMLC-Core代码解读与宏

    MXNet--DMLC-Core代码解读与宏 dmlc-core是Distributed (Deep) Machine Learning Community的一个基础模块,这个模块用被应用到了mxne ...

  4. 每周分享之 二 http协议(2)

    本次分享http协议,共分为三部分,这是第二部分,主要讲解请求与响应的字段,以及状态码. 以http/1.1版本的一个完整的请求与响应作为例子 http请求信息由三部分组成 1.请求方法(GET/PO ...

  5. Web的架构与html5基础知识

    图1:完整的Web应用构架 图2:html5的基本结构 head 可添加在头部标签元素有→→title meta style link base script noscript meta 几个重要属性 ...

  6. 非对称加密RSA的C#实现

    1.对称加密算法 对称加密是最快速.最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key). 对称加密有很多种算法,由于它效率很高,所 ...

  7. Unity3D - Animator Controller循环依赖

    问题 假设有2个Animator Controller,分别命名为TestControllerLhs.controller以及TestControllerRhs.controller.在TestCon ...

  8. MySQL笔记 存储过程 游标 触发器

    第二十三章 使用存储过程 MySQL5 中添加了存储过程的支持. 大多数SQL语句都是针对一个或多个表的单条语句.并非所有的操作都怎么简单.经常会有一个完整的操作需要多条才能完成 存储过程简单来说,就 ...

  9. web项目jsp出现The superclass javax.servlet.http.HttpServlet was not found on the Java Build Path错误

    原因是Javaweb工程类中没有添加Tomcat运行时相关类导致. 解决方式如下:出错的文件---->>build path---->>config build path--- ...

  10. php 变量 循环关键词以及方法

    <?php/* 多行注释 */常用数据类型int string double/float bool变量的定义$a = 123;$b = "123";$c = '456';$d ...