SQLAlchemy ORM教程之二:Query
Query
Session的query函數會返回一個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 FlinstoneQuery也接受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 FlinstoneQuery返回的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_by和filter。其中后者比起前者要更靈活一些,你可以在后者的參數中使用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:
- not equals:
- LIKE:
- IN:
- NOT IN:
- IS NULL:
- IS NOT NULL:
- AND:
- OR:
- MATCH:
?
返回列表(List)和單項(Scalar)
很多Query的方法執行了SQL命令并返回了取出的數據庫結果。
- all()返回一個列表:
- first()返回至多一個結果,而且以單項形式,而不是只有一個元素的tuple形式返回這個結果.
- 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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Twisted SSH
- 下一篇: Cowrie蜜罐的部署(ubt亲测)