SQLAlchemy复杂查询2018-08-02

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

包含contains

query.filter(User.addresses.contains(someaddress))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容