DDR爱好者之家 Design By 杰米

前期我们做了充足的准备工作,现在该是关键内容之一查询了,当然前面的文章中或多或少的穿插了些有关查询的东西,比如一个查询(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.”,不太明白这个操作的意思)

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

DDR爱好者之家 Design By 杰米
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
DDR爱好者之家 Design By 杰米

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。