SQLAlchemy复杂查询
最近个人用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复杂查询的更多相关文章
- pythonのsqlalchemy简单查询
#!/usr/bin/env python import sqlalchemy from sqlalchemy import create_engine from sqlalchemy.ext.dec ...
- flask 中orm关系映射 sqlalchemy的查询
flask的orm框架(SQLAlchemy)-一对多查询以及多对多查询 一对多,多对多是什么? 一对多.例如,班级与学生,一个班级对应多个学生,或者多个学生对应一个班级. 多对多.例如,学生与课 ...
- 【Flask】Sqlalchemy 子查询
### subquery:子查询可以让多个查询变成一个查询,只要查找一次数据库,性能相对来讲更加高效一点.不用写多个sql语句就可以实现一些复杂的查询.那么在sqlalchemy中,要实现一个子查询, ...
- SQLAlchemy的查询操作Query
查询操作 查询子句使用session的.query()方法来获取Query查询对象.查询对象能够使用一些方法来对应一些查询子句,比如.order_by(),.limit(),.filter()等. 查 ...
- SQLAlchemy -高级查询
查询 # -*- coding: utf-8 -*- from sqlalchemy.orm import sessionmaker from SQLAlchemy.create import ...
- day95:flask:SQLAlchemy数据库查询进阶&关联查询
目录 1.数据库查询-进阶 1.常用的SQLAlchemy查询过滤器 2.常用的SQLAlchemy查询结果的方法 3.filter 4.order_by 5.count 6.limit&of ...
- Python自动化之sqlalchemy关联查询
外键关联 from sqlalchemy import ForeignKey from sqlalchemy.orm import relationship class Address(Base): ...
- 【SQLAlchemy】SQLAlchemy修改查询字段列名
SQLAlchemy问题记录 company price quantity Microsoft Google Google Google 要实现脚本 select price, sum(quantit ...
- SQLAlchemy 在查询期间丢失与MySQL服务器的连接
遇到问题 pymysql.err.OperationalError: (2013, 'Lost connection to MySQL server during query') 建立的 pymysq ...
随机推荐
- MUI开发记录
最近很久没有更新博客了,因为一直在学习前端h5 手机app的开发.曾经一度觉得自己css和js学得不错,进入到前端领域后才发现水很深~ HUuilder使用安卓模拟器 安卓模拟器有很多,我这里以夜神模 ...
- Java 自增(++) 和 C语言中自增的区别
在Java.c语言等高级语言中自增和自减的作用基本一致,都是变量自身加一或减一.下面我只对自增进行说明,自减是类似的. 自增运算符(++),有两种书写形式,一个是在变量前: ++ num; 另一种在变 ...
- React Router 按需加载+服务器渲染的闪屏问题
伴随着React协议的『妥协』(v16采用MIT),React为项目的主体,这个在短期内是不会改变的了,在平时使用过程中发现了如下这个问题: 在服务器渲染的时候,刷新页面会出现闪屏的现象(白屏一闪而过 ...
- 我的Spring学习记录(四)
虽然Spring管理这我们的Bean很方便,但是,我们需要使用xml配置大量的Bean信息,告诉Spring我们要干嘛,这还是挺烦的,毕竟当我们的Bean随之增多的话,xml的各种配置会让人很头疼. ...
- Coin Change (II)(完全背包)
Coin Change (II) Time Limit: 1000MS Mem ...
- Windows中的硬链接和软链接(hard link 和 Symbolic link)
先来了解一下Linux中的硬链接和软链接: Linux中的硬链接和软链接 Windows中的硬链接和软链接: 硬链接 从Windows NT4开始,NTFS文件系统引入了HardLink这个概念,它让 ...
- php过滤textarea 中的换行符问题
之前我写的替换代码是这样的 $content = str_replace('\r\n', '', $_POST['content']); 为了确保window和Linux的换行符都能去掉,改成这样的: ...
- 定制自己的vue模版
前言 使用vue这个框架已经陆陆续续做了好几个项目了,不知不觉也已经在公司呆了4个月,转正了.时间如水...(省略一万字)./咳-不瞎扯了,公司是直接用的官方脚手架生成项目,官方模版没有vuex,ax ...
- Xadmin集成富文本编辑器ueditor
在xadmin中通过自定义插件,实现富文本编辑器,效果如下: 1.首先,pip安装ueditor的Django版本: pip install DjangoUeditor 2.之后需要添加到项目的set ...
- Java 线程并发
http://www.yesky.com/9/1899009.shtml http://zhidao.baidu.com/link?url=-xZ9JLo5x4bvCSVyXb2XhO6TODnBcU ...