赞
踩
介绍一下 Query 对象的使用
https://docs.sqlalchemy.org/en/latest/orm/tutorial.html#querying
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @Time : 2018/11/12 19:09 @File : query_data2.py @Author : frank.chang@shoufuyou.com query 对象 介绍 """ from base import session from model.creat_table import TUser if __name__ == '__main__': for instance in session.query(TUser).filter_by(name='frank25'): print(instance) print(instance.name, instance.mobile) for item in session.query(TUser.name,TUser.id).filter_by(name='frank25'): print(item) print(item.id,item.name)
结果如下:
<User(id='26', name='frank25', mobile='1234921325', password='edspassword25')>
frank25 1234921325
('frank25', 26)
26 frank25
query 里面可以过滤需要的字段,类似select 要选取的字段, 如果 query() 里面参数是类名,则返回所有字段.返回一个instance,
如果过滤字段的话, 需要跟上具体的字段. 当然 这时候返回是一个 ResultProxy.
也可以用 .name 去访问字段.
总结一下 query 里面 可以传入 类名.属性名, 来筛选 想要的字段.
来看下 first ,all one 的区别
saclar 是什么?
first
Return the first result of this Query or None if the result doesn’t contain any row.
first 如果没有结果, 返回为None, 如果有结果只返回第一条结果.这个方法不会往外抛异常。
all
This results in an execution of the underlying query.
all 会返回一个list
one
如果查询的结果是唯一的,可以用one , 如果用one,结果数据里面有多个或者没有都会报错.
会抛出异常 MultipleResultsFound , NoResultFound
这种我感觉适合主键的查询,比如说 id 的查询
one_or_none
如果查询结果是唯一的或者没有 可以用这个, 如果结果集有多个, 同样也会报错.
这个和one 的区别是,如果查询没有的情况下,返回None. 如果有的话,结果集必须是一个.
如果 有多个结果集 也会抛异常 MultipleResultsFound
scalar
这个感觉和first 比较像,也是返回第一个结果集,但是稍微有一点区别,这个查询如果
如果有多个也会抛异常。 而first 这个方法是不会往外抛异常的。
“”“Return the first element of the first result or None
if no rows present. If multiple rows are returned,
raises MultipleResultsFound.
“””
if __name__ == '__main__':
result = session.query(TUser).filter_by(name='frank5').all()
print("type(result):{}".format(type(result)))
for user in result:
print(user)
print("###" * 28)
result = session.query(TUser).filter_by(name='frank5').first()
print(result)
# 数据库里面没有name=frank5_ABC
result = session.query(TUser).filter_by(name='frank5_ABC').first()
print(result)
结果如下:
/Users/frank/.local/share/virtualenvs/mysqlalchemy-demo-0htClb7e/bin/python /Users/frank/PycharmProjects/mysqlalchemy-demo/query_data2.py
type(result):<class 'list'>
<User(id='6', name='frank5', mobile='123492135', password='edspassword5')>
<User(id='36', name='frank5', mobile='123492135', password='edspassword5')>
<User(id='46', name='frank5', mobile='123492135', password='edspassword5')>
####################################################################################
<User(id='6', name='frank5', mobile='123492135', password='edspassword5')>
None
Process finished with exit code 0
# 数据库里面没有数据
result = session.query(TUser).filter_by(id=100).one()
print(result)
错误如下:
sqlalchemy.orm.exc.NoResultFound: No row was found for one()
result = session.query(TUser).filter_by(id=100).one_or_none()
print(result) # None
如果查询结果集有多条记录,会抛异常 MultipleResultsFound
# 数据库里面有多条 name=frank5 的记录
result = session.query(TUser).filter_by(name='frank5').one_or_none()
print(result)
错误如下:
sqlalchemy.orm.exc.MultipleResultsFound: Multiple rows were found for one_or_none()
其实看下实现:
def one_or_none(self): """Return at most one result or raise an exception. Returns ``None`` if the query selects no rows. Raises ``sqlalchemy.orm.exc.MultipleResultsFound`` if multiple object identities are returned, or if multiple rows are returned for a query that returns only scalar values as opposed to full identity-mapped entities. Calling :meth:`.Query.one_or_none` results in an execution of the underlying query. .. versionadded:: 1.0.9 Added :meth:`.Query.one_or_none` .. seealso:: :meth:`.Query.first` :meth:`.Query.one` """ ret = list(self) l = len(ret) if l == 1: return ret[0] elif l == 0: return None else: raise orm_exc.MultipleResultsFound( "Multiple rows were found for one_or_none()")
首先把query 对象迭代一下, 拿到list 之后看list 的长度, 如果大于1,直接抛异常.
总结一下: one 用来查询仅有一条的记录, one_or_none 取仅有一条记录或者没有的记录。
first 用来查询记录中的第一条记录,如果没有记录,直接返回None.这个是不会抛异常的。
首先first 是取结果集中第一个结果,如果结果集没有则返回None,不会抛出异常的
one 结果集中有且仅有一个结果集,否则会抛异常出来 MultipleResultsFound,NoResultFound
而 salar 首先去掉one,如果,如果one 抛出NoResultFound异常, 则scalar 会返回一个空值,如果抛出MultipleResultsFound ,scalar 这个方法也会往外抛出这个异常。
def test_diff(myid):
result = session.query(TUser).filter(TUser.id == myid).scalar()
print('scalar result:')
print(result)
result2 = session.query(TUser).filter(TUser.id == myid).first()
print('first result:')
print(result2)
test_diff(10)
对于取id 操作,结果要么是有,要么没有。所以这样看起来结果是一样的。
结果如下:
scalar result:
<User(id='10', name='frank9', mobile='123492139', password='edspassword9')>
first result:
<User(id='10', name='frank9', mobile='123492139', password='edspassword9')>
如果filter 里面可以过滤多个结果集,scalar 就会报错了。
def test_diff_name(name): result2 = session.query(TUser).filter(TUser.name == name).first() print('first result:') print(result2) result = session.query(TUser).filter(TUser.name == name).scalar() print('scalar result:') print(result) test_diff_name('frank1')
结果如下,first可以成功取出一条,scalar 就会抛异常出来,MultipleResultsFound
first result:
<User(id='2', name='frank1', mobile='123492131', password='edspassword1')>
Traceback (most recent call last):
File "/Users/frank/.local/share/virtualenvs/mysqlalchemy-demo-0htClb7e/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2954, in one
ret = self.one_or_none()
File "/Users/frank/.local/share/virtualenvs/mysqlalchemy-demo-0htClb7e/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2933, in one_or_none
"Multiple rows were found for one_or_none()")
sqlalchemy.orm.exc.MultipleResultsFound: Multiple rows were found for one_or_none()
自我感觉 scalar 这个 函数有点鸡肋,本身 scalar 是调用 self.one() 方法,然后只是对没有结果的异常捕获了一下,然后返回None 值,对于MultipleResultsFound也是直接往外抛异常。
下面是 scalar 的实现代码
class Query:
def scalar(self):
try:
ret = self.one()
if not isinstance(ret, tuple):
return ret
return ret[0]
except orm_exc.NoResultFound:
return None
sqlalchemy 排序操作也很方便
1.可以直接导入这个包,进行操作
from sqlalchemy import asc, desc
if __name__ == '__main__':
query = session.query(TUser).order_by(desc(TUser.id)).limit(5)
print(query)
for ret in query:
print(ret)
直接用函数 desc 降序排序, asc 升序排序 ,order_by 后面 跟上要排序的字段就可以 了。
if __name__ == '__main__':
query = session.query(TUser).order_by(TUser.id.asc()).limit(5)
for ret in query:
print(ret)
结果如下:
<User(id='1', name='frank0', mobile='123492130', password='edspassword0')>
<User(id='2', name='frank1', mobile='123492131', password='edspassword1')>
<User(id='3', name='frank2', mobile='123492132', password='edspassword2')>
<User(id='4', name='frank3', mobile='123492133', password='edspassword3')>
<User(id='5', name='frank4', mobile='123492134', password='edspassword4')>
1.and的使用
if __name__ == '__main__':
query = session.query(TUser).filter_by(name='frank3')
for user in query:
print(user)
print('---' * 30)
query = session.query(TUser).filter_by(name='frank3', id=34)
print(query)
r = query.all()
print(r)
结果如下:
<User(id='4', name='frank3', mobile='123492133', password='edspassword3')>
<User(id='34', name='frank3', mobile='123492133', password='edspassword3')>
<User(id='44', name='frank3', mobile='123492133', password='edspassword3')>
------------------------------------------------------------------------------------------
SELECT `TUser`.create_time AS `TUser_create_time`, `TUser`.id AS `TUser_id`, `TUser`.name AS `TUser_name`, `TUser`.mobile AS `TUser_mobile`, `TUser`.password AS `TUser_password`
FROM `TUser`
WHERE `TUser`.name = %(name_1)s AND `TUser`.id = %(id_1)s
[<User(id='34', name='frank3', mobile='123492133', password='edspassword3')>]
if __name__ == '__main__':
# Query
query = session.query(TUser).filter(or_(TUser.name == 'frank1', TUser.name == 'frank29'))
print(query)
result = query.all()
for ret in result:
print(ret)
结果如下:query 打印出来sql 语句是用or 来查询
SELECT `TUser`.create_time AS `TUser_create_time`, `TUser`.id AS `TUser_id`, `TUser`.name AS `TUser_name`, `TUser`.mobile AS `TUser_mobile`, `TUser`.password AS `TUser_password`
FROM `TUser`
WHERE `TUser`.name = %(name_1)s OR `TUser`.name = %(name_2)s
<User(id='2', name='frank1', mobile='123492131', password='edspassword1')>
<User(id='30', name='frank29', mobile='1234921329', password='edspassword29')>
<User(id='32', name='frank1', mobile='123492131', password='edspassword1')>
<User(id='42', name='frank1', mobile='123492131', password='edspassword1')>
本文介绍了Query 的常用方法,first,all ,one 等以及之间的区别,介绍排序如何使用,筛选属性
联合查询 and, or_ 的用法。当然还有很多没有提及,可以看下官方文档,都有详细的介绍。
Query 对象有很多的用法,官方文档都有给出例子, 有时间的时候 ,多查询官方文档吧。
https://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.one
https://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.one_or_none
https://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.first
https://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.get
https://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.all
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。