SQLAlchemy復(fù)雜查詢2018-08-02

SQLAlchemy的查詢方式非常靈活,你所能想像到的復(fù)雜SQL 語句,基本上都可以實現(xiàn)。這里簡單的總結(jié)一下常用的查詢技巧。

1.多條件組合,可以用and_,or_實現(xiàn)。最外層時,and_可以省略,默認(rèn)用逗號分開條件。

  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.動態(tài)組合條件。針對不同的場景,可能需要不同的查詢條件,類似動態(tài)的拼接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.關(guān)聯(lián)查詢。對應(yīng)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包中。當(dāng)要對同一個表使用多次關(guān)聯(lián)時,可能需要用到別名。同時,如果查詢的結(jié)果有多個同名的字段,可以使用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.聚合查詢和使用數(shù)據(jù)庫函數(shù)。func可以調(diào)用各種聚合函數(shù),和當(dāng)前數(shù)據(jù)庫支持的其它函數(shù)。

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語句查詢。如果查詢實在太復(fù)雜,覺得用SQLAlchemy查詢方式很難實現(xiàn),或者要通過存儲過程實現(xiàn)查詢,可以讓SQLAlchemy直接運行SQL語句返回結(jié)果。

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))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容