Python ORM框架SQLAlchemy学习笔记之数据查询实例


Posted in Python onJune 10, 2014

前期我们做了充足的准备工作,现在该是关键内容之一查询了,当然前面的文章中或多或少的穿插了些有关查询的东西,比如一个查询(Query)对象就是通过Session会话的query()方法获取的,需要注意的是这个方法的参数数目是可变的,也就是说我们可以传入任意多的参数数目,参数的类型可以是任意的类组合或者是类的名称,接下来我们的例子就说明了这一点,我们让Query对象加载了User实例。

>>> for instance in session.query(User).order_by(User.id): 
...     print instance.name, instance.fullname
SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users ORDER BY users.id
()ed Ed Jones
wendy Wendy Williams
mary Mary Contrary
fred Fred Flinstone

当然通过这个例子我们得到Query对象返回的是一组可迭代的User实例表,然后我们通过for in语句访问,比如说这里可以依次输出“用户名”instance.name和“用户全名”instance.fullname。大家可能还注意到后面有个.order_by(User.id),这个和SQL语句一样的,指示结果集按User.id所映射的表列进行排序。

假设我们仅仅只需要“用户名”和“用户全名”,对于对象实例的其他属性不感兴趣的话,也可以直接查询它们(类的属性名称),当然这里的前提是这个类必须是ORM映射的,无论何时,任意数目的类实体或者基于列的实体均可以作为query()方法的参数,当然最终Query对象会返回元组类型。

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

返回的元组类型也可以被看作是普通的Python对象,属性名称归属性名称,类型名称归类型名称,比如下面的例子:
>>> for row in session.query(User, User.name).all(): 
...    print row.User, row.name
SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users
()<User('ed','Ed Jones', 'f8s7ccs')> ed
<User('wendy','Wendy Williams', 'foobar')> wendy
<User('mary','Mary Contrary', 'xxg527')> mary
<User('fred','Fred Flinstone', 'blah')> fred

当然你也可以搞点个性化,比如通过label()方法改变单独的列表达式名称,当然这个方法只有在映射到实体表的列元素对象(ColumnElement-derived)中存在(比如 User.name):
>>> for row in session.query(User.name.label('name_label')).all(): 
...    print(row.name_label)
SELECT users.name AS name_label
FROM users
()ed
wendy
mary
fred

之前我们看到查询对象实例必须用到实体类的全名(User),假设我们要多次使用这个实体类名作为查询对象(比如表连接操作)query()的参数,则我们可以给它取个“别名”,然后就可以通过别名来传入参数:
>>> from sqlalchemy.orm import aliased
>>> user_alias = aliased(User, name='user_alias')>>> for row in session.query(user_alias, user_alias.name).all(): 
...    print row.user_alias
SELECT user_alias.id AS user_alias_id,
        user_alias.name AS user_alias_name,
        user_alias.fullname AS user_alias_fullname,
        user_alias.password AS user_alias_password
FROM users AS user_alias
()
<User('ed','Ed Jones', 'f8s7ccs')>
<User('wendy','Wendy Williams', 'foobar')>
<User('mary','Mary Contrary', 'xxg527')>
<User('fred','Fred Flinstone', 'blah')>

学过MySQL等这类数据库的同学可能知道LIMIT和OFFSET这两个SQL操作,这个能够很方便的帮助我们控制记录的数目和位置,常常被用于数据分页操作,当然这类操作SQLAlchemy的Query对象已经帮我们想好了,而且很简单的可以通过Python数组分片来实现,这个操作常常和ORDER BY一起使用:
>>> for u in session.query(User).order_by(User.id)[1:3]: 
...    print u
SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users ORDER BY users.id
LIMIT ? OFFSET ?
(2, 1)<User('wendy','Wendy Williams', 'foobar')>
<User('mary','Mary Contrary', 'xxg527')>

假如我们需要筛选过滤特定结果,则可以使用filter_by()方法,这个方法使用关键词参数:
>>> for name, in session.query(User.name).\
...             filter_by(fullname='Ed Jones'): 
...    print name
SELECT users.name AS users_name FROM users
WHERE users.fullname = ?
('Ed Jones',)ed

或者使用filter()同样能达到目的,不过需要注意的是其使用了更加灵活的类似SQL语句的表达式结构,这意味着你可以在其内部使用Python自身的操作符,比如比较操作:
>>> for name, in session.query(User.name).\
...             filter(User.fullname=='Ed Jones'): 
...    print name
SELECT users.name AS users_name FROM users
WHERE users.fullname = ?
('Ed Jones',)ed

注意这里的User.fullname=='Ed Jones',比较操作与Ed Jones相等的才筛选。

当然强大的Query对象有个很有用的特性,那就是它是可以串联的,意味着Query对象的每一步操作将会返回一个Query对象,你可以将相同的方法串联到一起形成表达式结构,假如说我们要查询用户名为”ed”并且全名为”Ed Jones”的用户,你可以直接串联调用filter()两次,表示SQL语句里的AND连接:

>>> for user in session.query(User).\
...          filter(User.name=='ed').\
...          filter(User.fullname=='Ed Jones'): 
...    print user
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 = ? AND users.fullname = ?
('ed', 'Ed Jones')<User('ed','Ed Jones', 'f8s7ccs')>

下面列举一些使用filter()常见的筛选过滤操作:

1. 相等

query.filter(User.name == 'ed')

2. 不等
query.filter(User.name != 'ed')

3. LIKE
query.filter(User.name.like('%ed%'))

4. 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%'))))

5. NOT IN
query.filter(~User.name.in_(['ed', 'wendy', 'jack']))

6. IS NULL
filter(User.name == None)

7. IS NOT NULL
filter(User.name != None)

8. AND
from sqlalchemy import and_
filter(and_(User.name == 'ed', User.fullname == 'Ed Jones'))# or call filter()/filter_by() multiple times
filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')

9. OR
from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))

10. 匹配
query.filter(User.name.match('wendy'))

match()参数内容由数据库后台指定。(注:原文是“The contents of the match parameter are database backend specific.”,不太明白这个操作的意思)

好了,今天就介绍这么多,基本上都是蹩脚的翻译,希望对大家能够帮助

Python 相关文章推荐
python模拟新浪微博登陆功能(新浪微博爬虫)
Dec 24 Python
Python比较文件夹比另一同名文件夹多出的文件并复制出来的方法
Mar 05 Python
Python实现一个服务器监听多个客户端请求
Apr 12 Python
Python利用pandas计算多个CSV文件数据值的实例
Apr 19 Python
Python 读取图片文件为矩阵和保存矩阵为图片的方法
Apr 27 Python
python 获取键盘输入,同时有超时的功能示例
Nov 13 Python
python 用下标截取字符串的实例
Dec 25 Python
Python+Selenium+phantomjs实现网页模拟登录和截图功能(windows环境)
Dec 11 Python
python 通过手机号识别出对应的微信性别(实例代码)
Dec 22 Python
后端开发使用pycharm的技巧(推荐)
Mar 27 Python
浅谈keras中loss与val_loss的关系
Jun 22 Python
python 实现图与图之间的间距调整subplots_adjust
May 21 Python
Python ORM框架SQLAlchemy学习笔记之数据添加和事务回滚介绍
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之关系映射实例
Jun 10 #Python
Python ORM框架SQLAlchemy学习笔记之安装和简单查询实例
Jun 10 #Python
Python使用htpasswd实现基本认证授权的例子
Jun 10 #Python
python网络编程学习笔记(10):webpy框架
Jun 09 #Python
python网络编程学习笔记(九):数据库客户端 DB-API
Jun 09 #Python
You might like
PHP 读取文件的正确方法
2009/04/29 PHP
实现获取http内容的php函数分享
2014/02/16 PHP
PHP使用SOAP扩展实现WebService的方法
2016/04/01 PHP
thinkphp中的url跳转用法分析
2016/07/12 PHP
Thinkphp5行为使用方法汇总
2017/12/21 PHP
基于Jquery的$.cookie()实现跨越页面tabs导航实现代码
2011/03/03 Javascript
node.js中的fs.writeFileSync方法使用说明
2014/12/14 Javascript
javascript判断网页是关闭还是刷新
2015/09/12 Javascript
jQuery插件扩展测试实例
2016/06/21 Javascript
JS查找数组中重复元素的方法详解
2017/06/14 Javascript
jsonp跨域请求详解
2017/07/13 Javascript
深入浅析Vue中的Prop
2018/06/10 Javascript
vue插件开发之使用pdf.js实现手机端在线预览pdf文档的方法
2018/07/12 Javascript
基于vue如何发布一个npm包的方法步骤
2019/05/15 Javascript
微信小程序点击图片实现长按预览、保存、识别带参数二维码、转发等功能
2019/07/20 Javascript
vue实现评论列表功能
2019/10/25 Javascript
js回调函数仿360开机
2019/12/26 Javascript
解决qrcode.js生成二维码时必须定义一个空div的问题
2020/07/09 Javascript
Element PageHeader页头的使用方法
2020/07/26 Javascript
在Python中处理字符串之isdecimal()方法的使用
2015/05/20 Python
Python3实战之爬虫抓取网易云音乐的热门评论
2017/10/09 Python
解决python os.mkdir创建目录失败的问题
2018/10/16 Python
python根据txt文本批量创建文件夹
2020/12/08 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
2019/06/04 Python
pytorch 求网络模型参数实例
2019/12/30 Python
python使用信号量动态更新配置文件的操作
2020/04/01 Python
python查找特定名称文件并按序号、文件名分行打印输出的方法
2020/04/24 Python
pycharm最新激活码有效期至2100年(亲测可用)
2021/02/05 Python
h5页面背景图很长要有滚动条滑动效果的实现
2021/01/27 HTML / CSS
Omio西班牙:全欧洲低价大巴、火车和航班搜索和比价
2017/02/11 全球购物
德国团购网站:Groupon德国
2018/03/13 全球购物
地球鞋加拿大官网:Earth Shoes Canada
2020/11/17 全球购物
一套VC试题
2015/01/23 面试题
张丽莉事迹观后感
2015/06/16 职场文书
Python实现简单的俄罗斯方块游戏
2021/09/25 Python
MySQL数据管理操作示例讲解
2022/12/24 MySQL