SQLAlchemy複雜查詢

2022-01-25 15:55:59 字數 3425 閱讀 8374

最近個人用python + flask搞了乙個小專案,orm用到的是sqlalchemy。

sqlalchemy的查詢方式非常靈活,你所能想像到的複雜sql 語句,基本上都可以實現。這裡簡單的總結一下常用的查詢技巧。

多條件組合,可以用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()

動態組合條件。針對不同的場景,可能需要不同的查詢條件,類似動態的拼接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()

關聯查詢。對應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()

使用別名用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()

聚合查詢和使用資料庫函式。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()

子查詢。 

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()

直接執行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()

分頁查詢。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的關聯子查詢

sqlalchemy也算是用過好幾年了,不過一直都用著其中相對簡單的一小部分,最近寫個程式碰到個問題,需要作乙個關聯子查詢,類似這樣的sql語句 select master.select count from detail where detail.parentid master.id and de...

SQLAlchemy 查詢(限制,偏移,排序)

先對所要查詢的表進行排序,然後是所要查詢的內容newslist news.query order by db.desc news.n id filter by n is del false 查詢兩張表,不需要外來鍵result1 jobfair.query join company,jobfair....

SQLAlchemy的查詢操作Query

查詢操作 查詢子句使用session的.query 方法來獲取query查詢物件。查詢物件能夠使用一些方法來對應一些查詢子句,比如.order by limit filter 等。查詢物件有這麼幾種方法.one all scalar one or none get 以及.first 等。下面對這幾個...