Query

Sessionquery函数会返回一个Query对象。query函数可以接受多种参数类型。可以是类,或者是类的instrumented descriptor。下面的这个例子取出了所有的User记录。

>>> for instance in session.query(User).order_by(User.id):
...     print(instance.name, instance.fullname)
ed Ed Jones
wendy Wendy Williams
mary Mary Contrary
fred Fred Flinstone

Query也接受ORM-instrumented descriptors作为参数。当多个参数传入时,返回结果为以同样顺序排列的tuples

>>> for name, fullname in session.query(User.name, User.fullname):
...     print(name, fullname)
ed Ed Jones
wendy Wendy Williams
mary Mary Contrary
fred Fred Flinstone

Query返回的tuples由KeyedTuple这个类提供,其成员除了用下标访问意外,还可以视为实例变量来获取。对应的变量的名称与被查询的类变量名称一样,如下例:

>>> for row in session.query(User, User.name).all():
...    print(row.User, row.name)
<User(name='ed', fullname='Ed Jones', password='f8s7ccs')> ed
<User(name='wendy', fullname='Wendy Williams', password='foobar')> wendy
<User(name='mary', fullname='Mary Contrary', password='xxg527')> mary
<User(name='fred', fullname='Fred Flinstone', password='blah')> fred

你可以通过label()来制定descriptor对应实例变量的名称

>>> for row in session.query(User.name.label('name_label')).all():
...    print(row.name_label)
ed
wendy
mary
fred

而对于类参数而言,要实现同样的定制需要使用aliased

>>> from sqlalchemy.orm import aliased
>>> user_alias = aliased(User, name='user_alias')SQL>>> for row in session.query(user_alias, user_alias.name).all():
...    print(row.user_alias)
<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>
<User(name='wendy', fullname='Wendy Williams', password='foobar')>
<User(name='mary', fullname='Mary Contrary', password='xxg527')>
<User(name='fred', fullname='Fred Flinstone', password='blah')>

基本的查询操作除了上面这些之外,还包括OFFSET和LIMIT,这个可以通过Python的array slice来完成。

>>> for u in session.query(User).order_by(User.id)[1:3]:
...    print(u)
<User(name='wendy', fullname='Wendy Williams', password='foobar')>
<User(name='mary', fullname='Mary Contrary', password='xxg527')>

上述过程实际上只涉及了整体取出的操作,而没有进行筛选,筛选常用的函数是filter_byfilter。其中后者比起前者要更灵活一些,你可以在后者的参数中使用python的运算符。

>>> for name, in session.query(User.name).\
...             filter_by(fullname='Ed Jones'):
...    print(name)
ed
>>> for name, in session.query(User.name).\
...             filter(User.fullname=='Ed Jones'):
...    print(name)
ed

注意Query对象是generative的,这意味你可以把他们串接起来调用,如下:

>>> for user in session.query(User).\
...          filter(User.name=='ed').\
...          filter(User.fullname=='Ed Jones'):
...    print(user)
<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>

串接的filter之间是的关系。

常用的filter操作符

下面的这些操作符可以应用在filter函数中

  • equals:
query.filter(User.name == 'ed')
  • not equals:
query.filter(User.name != 'ed')
  • LIKE:
query.filter(User.name.like('%ed%'))
  • IN:
query.filter(User.name.in_(['ed', 'wendy', 'jack']))# works with query objects too:
query.filter(User.name.in_(session.query(User.name).filter(User.name.like('%ed%'))
))
  • NOT IN:
query.filter(~User.name.in_(['ed', 'wendy', 'jack']))
  • IS NULL:
query.filter(User.name == None)# alternatively, if pep8/linters are a concern
query.filter(User.name.is_(None))
  • IS NOT NULL:
query.filter(User.name != None)# alternatively, if pep8/linters are a concern
query.filter(User.name.isnot(None))
  • AND:
# use and_()
from sqlalchemy import and_
query.filter(and_(User.name == 'ed', User.fullname == 'Ed Jones'))# or send multiple expressions to .filter()
query.filter(User.name == 'ed', User.fullname == 'Ed Jones')# or chain multiple filter()/filter_by() calls
query.filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')
  • OR:
from sqlalchemy import or_
query.filter(or_(User.name == 'ed', User.name == 'wendy'))
  • MATCH:
query.filter(User.name.match('wendy'))

返回列表(List)和单项(Scalar)

很多Query的方法执行了SQL命令并返回了取出的数据库结果。

  • all()返回一个列表:
>>> query = session.query(User).filter(User.name.like('%ed')).order_by(User.id)
SQL>>> query.all()
[<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>,<User(name='fred', fullname='Fred Flinstone', password='blah')>]
  • first()返回至多一个结果,而且以单项形式,而不是只有一个元素的tuple形式返回这个结果.
>>> query.first()
<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>
  • one()返回且仅返回一个查询结果。当结果的数量不足一个或者多于一个时会报错。
>>> user = query.one()
Traceback (most recent call last):
...
MultipleResultsFound: Multiple rows were found for one()

没有查找到结果时:

>>> user = query.filter(User.id == 99).one()
Traceback (most recent call last):
...
NoResultFound: No row was found for one()
  • one_or_none():从名称可以看出,当结果数量为0时返回None, 多于1个时报错

  • scalar()one()类似,但是返回单项而不是tuple

嵌入使用SQL

你可以在Query中通过text()使用SQL语句。例如:

>>> from sqlalchemy import text
>>> for user in session.query(User).\
...             filter(text("id<224")).\
...             order_by(text("id")).all():
...     print(user.name)
ed
wendy
mary
fred

除了上面这种直接将参数写进字符串的方式外,你还可以通过params()方法来传递参数

>>> session.query(User).filter(text("id<:value and name=:name")).\
...     params(value=224, name='fred').order_by(User.id).one()
<User(name='fred', fullname='Fred Flinstone', password='blah')>

并且,你可以直接使用完整的SQL语句,但是要注意将表名和列明写正确。

>>> session.query(User).from_statement(
...                     text("SELECT * FROM users where name=:name")).\
...                     params(name='ed').all()
[<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>]

计数

Query定义了一个很方便的计数函数count()

>>> session.query(User).filter(User.name.like('%ed')).count()
SELECT count(*) AS count_1
FROM (SELECT users.id AS users_id,users.name AS users_name,users.fullname AS users_fullname,users.password AS users_password
FROM users
WHERE users.name LIKE ?) AS anon_1
('%ed',)
2

注意上面我们同时列出了实际的SQL指令。在SQLAlchemy中,我们总是将被计数的查询打包成一个子查询,然后对这个子查询进行计数。即便是最简单的SELECT count(*) FROM table,也会如此处理。为了更精细的控制计数过程,我们可以采用func.count()这个函数。

>>> from sqlalchemy import func
SQL>>> session.query(func.count(User.name), User.name).group_by(User.name).all()
SELECT count(users.name) AS count_1, users.name AS users_name
FROM users GROUP BY users.name
()
[(1, u'ed'), (1, u'fred'), (1, u'mary'), (1, u'wendy')]

为了实现最简单的SELECT count(*) FROM table,我们可以如下调用

>>> session.query(func.count('*')).select_from(User).scalar()
SELECT count(?) AS count_1
FROM users
('*',)
4

如果我们对User的主键进行计数,那么select_from也可以省略。

>>> session.query(func.count(User.id)).scalar()
SELECT count(users.id) AS count_1
FROM users
()
4

SQLAlchemy ORM教程之二:Query相关推荐

  1. 乐鑫代理-启明云端分享ESP32系列教程之二:Linux搭建esp-idf环境

    提示:此教程依据乐鑫官方的ESP32入门教程总结而来,仅供个人参考学学习,如有错误,欢迎批评指正.乐鑫官方参考: 乐鑫官方文档地址 1.搭建esp-idf环境 1.1安装虚拟机与Ubuntu 未安装请 ...

  2. SAP UI5 初学者教程之二:SAP UI5 的引导过程(Bootstrap) 试读版

    Jerry 从 2014 年加入 SAP成都研究院 CRM Fiori 开发团队之后开始接触 SAP UI5,曾经在 SAP 社区和"汪子熙"微信公众号上发表过多篇关于 SAP U ...

  3. 【SAP PO】SAP PO 接口配置完整教程之二REST服务对接

    SAP PO 接口配置完整教程之二REST服务对接 1.了解服务协议 1.1.服务通讯协议 1.2.具体接口协议 1.3.接口服务测试 2.PO端接口配置 2.1.PO端ESR配置 2.2.PO端IB ...

  4. NVIDIA Jetson TX1 系列开发教程之二:刷机与开发前准备

    NVIDIA Jetson TX1 系列开发教程之二:刷机与开发前准备 转载请注明作者和出处:http://blog.csdn.net/u011475210 嵌入式平台:NVIDIA Jetson T ...

  5. github打开前端样式丢失_微信小程序入门教程之二:页面样式

    这个系列的上一篇教程,教大家写了一个最简单的 Hello world 微信小程序. 但是,那只是一个裸页面,并不好看.今天接着往下讲,如何为这个页面添加样式,使它看上去更美观,教大家写出实际可以使用的 ...

  6. image 微信小程序flex_微信小程序入门教程之二:页面样式

    这个系列的上一篇教程,教大家写了一个最简单的 Hello world 微信小程序. 但是,那只是一个裸页面,并不好看.今天接着往下讲,如何为这个页面添加样式,使它看上去更美观,教大家写出实际可以使用的 ...

  7. U-Boot移植教程之二:移植

    内容来自 韦东山<嵌入式Linux应用开发完全手册> 一.U-Boot移植 开发板smdk2410的配置适用于大多数S3C2410单板,或是只需要极少的修改即可使用.但是目前U-Boot中 ...

  8. RabbitMQ系列教程之二:工作队列(Work Queues)

    今天开始RabbitMQ教程的第二讲,废话不多说,直接进入话题.   (使用.NET 客户端 进行事例演示) 在第一个教程中,我们编写了一个从命名队列中发送和接收消息的程序.在本教程中,我们将创建一个 ...

  9. cnn 验证集 参与训练吗_一个简单的零基础的机器学习教程之二,字母数字验证码识别...

    一.前言 基于前面我发的贴子 土味程序员:一个简单的零基础的机器学习教程,Pytorch搭建Faster R-CNN目标检测平台​zhuanlan.zhihu.com 一个非常震撼的目标检测的例子.上 ...

最新文章

  1. 干货,Wireshark使用技巧-过滤规则
  2. 29.CSS3边框图片效果
  3. 二十万字C/C++、嵌入式软开面试题全集宝典五
  4. MapReduce太慢了,记一次对它的调优建议。
  5. Java中的三目运算符可能出现的问题
  6. 如何为部署到 SAP BTP 平台上的 Node.js 应用提供Authorization 和 Trust 管理 - 权限管控
  7. 数据结构---排序算法的总结
  8. Android 基础(十三) shape
  9. python的jieba分词
  10. php 日期 星期_php日期如何转星期
  11. 树形背包O(n * v^2)入门
  12. win10计算机网络共享设置密码,win10局域网设置密码如何设置_win10局域网怎么设置访问密码-win7之家...
  13. CSS 幻术 | 抗锯齿
  14. 为markdown目录标题添加序号
  15. ERP软件是什么意思,买菜大妈讲的通俗易懂
  16. 投屏类H5应用开发分析
  17. 微信这几个好用的功能,你该知道
  18. 微信小程序:小程序内用户帐号登录规范调整和优化建议
  19. 关于访问 WIN10共享打印机提示 无法连接到打印机的问题
  20. 利用FastReport传递图片参数,在报表上展示签名信息

热门文章

  1. 精选| 2021年2月R新包推荐(第51期)
  2. 一个函数统一238个机器学习R包,这也太赞了吧
  3. GEO2R/GEOquery的结果可能是错的!!!
  4. M1芯片Mac也可以安装Windows系统啦 使用PD16虚拟机安装ARM版Windows10教程
  5. java immutable系列_Java Immutable类代码示例
  6. 信息学奥赛一本通 提高篇 第六部分 数学基础 第1章 快速幂
  7. python程序可以在任何安装了解释器_Python解释器新手安装教程
  8. 计算机网络-VRRP
  9. Java工作笔记-生成及解析Json字符串
  10. Qt + Python + OpenCV图标替换工具 之 项目介绍(一)