查询

  1. # -*- coding: utf-8 -*-  

  2. from sqlalchemy.orm import sessionmaker  

  3. from SQLAlchemy.create import engine,User  

  4. Session = sessionmaker(engine)  

  5. db_session = Session()  

  6.             
     
  7. query = db_session.query(User).filter(User.name.like('%2%')).order_by(User.id)  

  8.             
     
  9. # ------> 查询 all list  
  10. print(query.all())  

  11.             
     
  12. # ------> first() 第一个  

  13. print(query.first())  

  14.             
     
  15. # ------> one()  如果这个结果集少于或者多于一条数据, 结论有且只有一条数据的时候才会正常的返回,否则抛出异常  

  16. print(query.one())  

  17.             
     
  18. # ------> one_or_none() 在结果集中没有数据的时候也不会抛出异常  

  19.             
     
  20. # ------> scalar()  底层调用one()方法,并且如果one()方法没有抛出异常,会返回查询到的第一列的数据  

  21. query2 = db_session.query(User).filter(User.name=="2").scalar()  

  22. print(query2)  

  23.             
     
  24. # ------> text  

  25. from sqlalchemy import text  

  26. query3 = db_session.query(User).filter(text("id<3")).order_by(text('id'))  

  27. print(query3.all())  

  28.             
     
  29. # text 带变量方式 用 :传入变量,用params接收  

  30. query4 = db_session.query(User).filter(text("id<:value")).params(value=4)  

  31. print(query4.all())  

  32.             
     
  33. # from_statement 原生sql语句  

  34. query5 = db_session.query(User).from_statement(text("select * from user where id>:value")).params(value=2).all()  

  35. print(query5)  

  36.  
     
  37. # ------> and_ or_ 普通的表达式在这里面不好使  
  38. from sqlalchemy.sql import and_, or_    
  39. query6 = db_session.query(User).filter(and_(User.id==1, User.name=="ewqe")).first()  
  40. print(query6.id)  
  41. # 结果 1  
  42.   
     
  43. query7 = db_session.query(User).filter(or_(User.id==1, User.name=="rre")).all()  
  44. print([i.id for i in query7])  
  45. # 结果 [1, 3]  
  46.  
  47. # ------> between 大于多少小于多少  
  48. query8 = db_session.query(User).filter(User.id.between(1, 3)).all()  
  49. print(query8)  
  50.   
     
  51. # ------> in_  在里面对应还有not in等  
  52. query9 = db_session.query(User).filter(User.id.in_([1])).all()  
  53. print(query9)  
  54.  
     
  55. # ------> synchronize_session
  56. # synchronize_session=False 在原有值的基础上增加和删除 099 str  
  57. db_session.query(User).filter(User.id > 0).update({User.name: User.name + '099'}, synchronize_session=False)  
  58. db_session.commit()  
  59.   
     
  60. # synchronize_session=evaluate 在原有值的基础上增加和减少 11, 必须是整数类型  
  61. db_session.query(User).filter(User.id > 0).update({"name": User.name + 1}, synchronize_session="evaluate")  
  62. db_session.commit()  
  63.   
     
  64. # 如果查询条件里有in_,需要在delete()中加如下参数: fetch  删除的更快  
  65. query10 = db_session.query(User).filter(User.id.in_([1, 2])).delete(synchronize_session='fetch')  
  66. print(query10) # 返回找到的数量  
  67. db_session.commit() 
  68.  

           
 

计数(Count)

  1. 有时候你想明确的计数,比如要统计users表中有多少个不同的姓名,  

  2. 那么简单粗暴的采用以上count是不行的,因为姓名有可能会重复,  

  3. 但是处于两条不同的数据上,如果在原生数据库中,可以使用distinct关键字,  

  4. 那么在SQLAlchemy中,可以通过func.count()方法来实现  

  5. from sqlalchemy import func  

  6. query1 = db_session.query(func.count(User.name)).first() #  (4,)  

  7.           
     
  8. # 如果想实现select count(*) from users,可以通过以下方式来实现:  

  9. query2 = db_session.query(func.count("*")).select_from(User).scalar() # 4  

  10.           
     
  11. # 如果指定了要查找的表的字段,可以省略select_from()方法:  

  12. query3 = db_session.query(func.count(User.id)).scalar() # 4  

   
 

排序

  1. order_by:可以指定根据这个表中的某个字段进行排序,如果在前面加了一个-,代表的是降序排序    

  2. 正向排序和反向排序:默认情况是从小到大,从前到后排序的,如果想要反向排序,可以调用排序的字段的desc方法。  

一.
relationship的order_by参数 

teachers = relationship('Teacher',secondary=association_table, back_populates='classes', order_by=Teacher.name)  

二. 在模型定义中,添加以下代码:  

  1.     __mapper_args__ = {  

  2.      "order_by": name  

  3.    }  

   
 

limit、offset和切片

  1. limit:可以限制每次查询的时候只查询几条数据。  

  2. offset:可以限制查找数据的时候过滤掉前面多少条。  

  3. 切片:可以对Query对象使用切片操作,来获取想要的数据。  

  4.       
     
  5. all = db_session.query(Teacher).limit(2).all()  

  6. print([i.id for i in all ])  

  7. # 结果 [1, 2]  

  8.       
     
  9. all2 = db_session.query(Teacher).limit(2).offset(1).all()  

  10. print([i.id for i in all2])  

  11. # 结果 [2, 3]  

   
 

懒加载

  1. 在一对多,或者多对多的时候,如果想要获取多的这一部分的数据的时候,往往能通过一个属性就可以全部获取了。  

  2. 比如有一个作者,想要或者这个作者的所有文章,那么可以通过user.articles就可以获取所有的。  

  3. 但有时候我们不想获取所有的数据,比如只想获取这个作者今天发表的文章,  

  4. 那么这时候我们可以给relationship传递一个lazy='dynamic',  

  5. 以后通过user.articles获取到的就不是一个列表,而是一个AppendQuery对象了。  

  6. 这样就可以对这个对象再进行一层过滤和排序等操作  

   
 

group_by

比如我想根据名字来分组, 统计每个名字分组里面有多少人  

  1. from sqlalchemy import func  

  2. # 我想根据名字来分组, 统计每个名字分组里面有多少人  

  3. all = db_session.query(Teacher.name, func.count(Teacher.id)).group_by(Teacher.name).all()  

   
 

having

  1. having是对查找结果进一步过滤。比如只想要看未成年人的数量,那么可以首先对年龄进行分组统计人数,然后再对分组进行having过滤  

  2.       
     
  3. result = session.query(User.age,func.count(User.id)).group_by(User.age).having(User.age >= 18).all()  

   
 

join方法

表结构

  1. class Address(Base):  

  2.     __tablename__ = 'address'  

  3.     id = Column(Integer, primary_key=True)  

  4.     name = Column(String(32))  

  5.     user_id = Column(Integer,ForeignKey("user.id"))  # 外键关系 Fk  

  6.     
     
  7.     
     
  8. class User(Base):  

  9.     __tablename__ = 'user'  

  10.     id = Column(Integer, primary_key=True)  

  11.     name = Column(String(32))

 
 

  1. ---> 普通查询  

  2. all = db_session.query(User, Address).filter(User.id == Address.user_id).all()  

  3. for u, a in all:  

  4.     print(u.name, a.name)  

  5.         
     
  6. 输出结果  

  7. peach 地址1  

  8. peach 地址2  

  9. peach 地址3  

  10.     
     
  11. ---> join查询  

  12. all = db_session.query(User, Address).join(Address).all()  

  13. for u, a in all:  

  14.     print(u.name, a.name)  

  15.         
     
  16. 输出结果  

  17. peach 地址1  

  18. peach 地址2  

  19. peach 地址3  

  20.     
     
  21. ---> outerjoin查询 left join是以左边为准 right 是以右边为准  

  22. all = db_session.query(User, Address).outerjoin(Address).all()  

  23. for u in all:  

  24.     print(u)  

  25.     
     
  26. 输出结果  

  27. (<__main__.User object at 0x7fb9e3160518><__main__.Address object at 0x7fb9e3160588>)  

  28. (<__main__.User object at 0x7fb9e3160518><__main__.Address object at 0x7fb9e31605f8>)  

  29. (<__main__.User object at 0x7fb9e3160518><__main__.Address object at 0x7fb9e3160668>)  

  30. (<__main__.User object at 0x7fb9e31606d8>, None)  

 
 

别名

  1. # 当多表查询的时候,有时候同一个表要用到多次,这时候用别名就可以方便的解决命名冲突的问题了  

  2. from sqlalchemy.orm import aliased  

  3. adalias1 = aliased(Address)  

  4. adalias2 = aliased(Address)  

  5.     
     
  6. for username, ad1name, ad2name in db_session.query(User.name, adalias1.name, adalias2.name).join(adalias1).all():  

  7.     print(username, ad1name, ad2name)  

 
 

子查询

  1. # 构造子查询  

  2. # 首先查询用户有多少地址  

  3. from sqlalchemy.sql import func  

  4. addr = db_session.query(Address.user_id.label('user_id'), func.count("*").label('address_count')).group_by(Address.user_id).all()  

  5. # 结果  

  6. 个地址  

  7. .label('user_id') 是取的别名  

 
 

  1. # 将子查询放到父查询中  

  2. addrs = db_session.query(Address.user_id.label('user_id'), func.count("*").label('address_count')).group_by(Address.user_id).subquery() # 子查询语句  

  3. for u,count in db_session.query(User,addrs.c.address_count).outerjoin(addrs,User.id==addrs.c.user_id).order_by(User.id):  

  4.     print(u.name,count)  

  5.     
     
  6. # 结果  

  7. # peach 3  

  8. # peach2 None  

  9.     
     
  10. # 一个查询如果想要变为子查询,则是通过subquery()方法实现  

  11. # 变成子查询后,通过子查询.c属性来访问查询出来的列  

  12. # 以上方式只能查询某个对象的具体字段  

 
 

以上方式只能查询某个对象的具体字段,如果要查找整个实体,则需要通过aliased方法

 
 

 
 

  

SQLAlchemy -高级查询的更多相关文章

  1. MongoDB高级查询详细

    前言 前几篇,老玩家绕道即可,新手晚上闲着也是蛋疼,不如把命令敲一边,这样你就会对MongoDB有一定的掌握啦.如果没有安装MongoDB去看我的上一篇博客  MongoDB下载安装与简单增删改查 前 ...

  2. T-SQL高级查询语句

    高级查询 1.连接查询,对结果集列的扩展select * from info select * from info,nation #形成笛卡尔积select * from info,nation wh ...

  3. SQL Server高级查询

    简介 关于数据库,我们经常会听说"增查删改"之类的词语,听起来很简单,但是如果想要准确的获取到需要的数据的话,还是要花点功夫的.下面由我来和大家谈谈高级查询的用法以及和普通查询的区 ...

  4. mongodb高级查询

    前几篇,老玩家绕道即可,新手晚上闲着也是蛋疼,不如把命令敲一边,这样你就会对MongoDB有一定的掌握啦.如果没有安装MongoDB去看我的上一篇博客  MongoDB下载安装与简单增删改查 前奏:启 ...

  5. MySQL高级查询语句

    高级查询: 一:多表连接 1.select Info.Code,Info.Name,Nation.Name from Info,Nation where Info.Nation = Nation.Co ...

  6. 10月17日下午MySQl数据库CRUD高级查询

    高级查询:1.连接查询 #适用于有外键关系的  没有任何关系没法用select * from Info,Nation #同时查询这俩表并把两表每个数据相互组合,形成笛卡尔积 select * from ...

  7. Mysql 基础 高级查询

    在西面内容中    car  和  nation   都表示 表名 1.无论 高级查询还是简单查询   都用  select.. from..语句   from  后面 加表名  可以使一张表也可以是 ...

  8. LinQ 高级查询

    高级查询 模糊查(包含):.Contains(name) 开头:.StartsWith(name) 结尾:.EndsWith(name) 个数:.Count() 最大值:Max(r => r.p ...

  9. SNF开发平台WinForm之五-高级查询使用说明-SNF快速开发平台3.3-Spring.Net.Framework

    5.1运行效果: 5.2开发实现: 1.按上面效果来说,先来看一下在程序当中如果调用.第一步在页面拖拽一个按钮为“高级查询”,事件上写下如下代码: 如果是单表查询的话,只需要传GridView就行,如 ...

随机推荐

  1. Docker最全教程——从理论到实战(二十三)

    如何节约云端成本? 上云在大部分情况下就是为了降低成本,在这方面,主流的容器服务基本上都能够有效地降低成本——不仅能够高效自动化的管理和控制容器,而且不需支付Kubernetes 主节点的费用.不过, ...

  2. [USACO09JAN]Total Flow【网络流】

    Farmer John always wants his cows to have enough water and thus has made a map of the N (1 <= N & ...

  3. IDEA全局搜索

    搜索文件名:连续按两下Shift键 搜索字符串:Ctrl + Shift +F

  4. 小I的小姐姐

    小 I 的小姐姐 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 小 I 去天津玩啦,一路上,他跟他的同学发生了许多有趣 ...

  5. [USACO10MAR] 伟大的奶牛聚集 - 树形dp

    每个点有重数,求到所有点距离最小的点 就是魔改的重心了 #include <bits/stdc++.h> using namespace std; #define int long lon ...

  6. 回形数字矩阵(Java)

    将矩阵从里到外分为多层,每一层都是一个口字型数字序列,方向都是顺时针/逆时针,由此我们可以将问题分解为相同的子问题来解决 回形矩阵概述 ☃ 回形矩阵有n行n列 ☃ 数字按顺时针或者逆时针递增 **使用 ...

  7. mysql视图的创建、基本操作、作用

    一.mysql视图的创建 作用:提高了重用性,就像一个函数.如果要频繁获取user的name和goods的name.就应该使用以下sql语言.示例: 先创建3张表 1.1user表 1.2goods表 ...

  8. 复选框与bitmap算法实践

    bitmap(位图)算法 bitmap算法是利用数据二进制的每一位的值来表示数据的算法,可用来压缩保存数据集. 如何保存 如 5(int)的二进制表示为 101b,第一位和第三位的值是1就可以表示数据 ...

  9. Java上转型和下转型

    Java 转型问题其实并不复杂,只要记住一句话:父类引用指向子类对象. 什么叫父类引用指向子类对象,且听我慢慢道来. 从2个名词开始说起:向上转型(upcasting) .向下转型(downcasti ...

  10. SPDK-nvmf与不同传输类型的公共接口

    SPDK-nvmf与不同传输类型的公共接口 不同类型的传输层到nvmf的公共命令请求接口 nvmf_fc_hwqp_handle_request() -->cmd_iu = buffer-> ...