flask
flask_ext
python
sqlalchemy
SQLAlchemy的query類有著很多的method,了解它對我們利用orm操作資料庫有著非常大的幫助,這邊也單純的記錄著個人可以理解的method說明。
註:以專案中的資料表為例
註:Blog_Main是blog的主表、Blog_Post是blog的明細表
>>> post = Blog_Post.query.all()
>>> len(post)
17
>>> type(post)
<class 'list'>
>>> post = Blog_Main.query.with_entities(Blog_Main.id, Blog_Main.author)
>>> pprint(post.column_descriptions)
[{'aliased': False,
'entity': <class 'app_blog.blog.model.Blog_Main'>,
'expr': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x05661540>,
'name': 'id',
'type': Integer()},
{'aliased': False,
'entity': <class 'app_blog.blog.model.Blog_Main'>,
'expr': <sqlalchemy.orm.attributes.InstrumentedAttribute object at 0x05661870>,
'name': 'author',
'type': Integer()}]
>>> post = Blog_Post.query
>>> post.count()
17
post = Blog_Post.query.filter_by(blog_main_id=1)
post.count()
10
>>> post = Blog_Post.query.filter(Blog_Post.id>1, Blog_Post.blog_main_id==1)
>>> str(post.statement)
'SELECT "Blog_Posts".id, "Blog_Posts".title,
"Blog_Posts".body, "Blog_Posts".category_id,
"Blog_Posts".author_id, "Blog_Posts".blog_main_id,
"Blog_Posts".create_date, "Blog_Posts".edit_date,
"Blog_Posts".slug, "Blog_Posts".flag \nFROM "Blog_Posts"
WHERE "Blog_Posts".id > :id_1 AND
"Blog_Posts".blog_main_id = :blog_main_id_1'
>>> post = Blog_Post.query.filter_by(id=1).all()
>>> post
[<POST> Flask]
>>> post = Blog_Post.query.filter_by(id=1, blog_main_id=1)
>>> str(post.statement)
'SELECT "Blog_Posts".id, "Blog_Posts".title,
"Blog_Posts".body, "Blog_Posts".category_id,
"Blog_Posts".author_id, "Blog_Posts".blog_main_id,
"Blog_Posts".create_date, "Blog_Posts".edit_date,
"Blog_Posts".slug, "Blog_Posts".flag \nFROM "Blog_Posts"
WHERE "Blog_Posts".id = :id_1 AND
"Blog_Posts".blog_main_id = :blog_main_id_1'
>>> post = Blog_Post.query.first()
>>> post
<POST> Flask
>>> post = Blog_Main.query.with_entities(Blog_Main.id, Blog_Main.author)
>>> print(post.statement)
SELECT "Blog_Main".id, "Blog_Main".author
FROM "Blog_Main"
>>> print(post.from_self().statement)
SELECT anon_1."Blog_Main_id", anon_1."Blog_Main_author" FROM
(SELECT "Blog_Main".id AS "Blog_Main_id", "Blog_Main".author AS "Blog_Main_author"
FROM "Blog_Main")
AS anon_1
>>> post = Blog_Main.query.filter(Blog_Main.blog_name.like('Flask%')).with_entities(Blog_Main.id, Blog_Main.author)
>>> print(post.from_self().statement)
SELECT anon_1."Blog_Main_id", anon_1."Blog_Main_author"
FROM (SELECT "Blog_Main".id AS "Blog_Main_id", "Blog_Main".author AS "Blog_Main_author"
FROM "Blog_Main"
WHERE "Blog_Main".blog_name LIKE :blog_name_1) AS anon_1
from sqlalchemy import text
>>> from sqlalchemy import text
>>> str = 'select id from Blog_posts'
>>> post = Blog_Post.query.from_statement(text(str))
>>> print(post.statement)
select id from Blog_posts
>>> from sqlalchemy import text
>>> str = 'select id from Blog_posts'
>>> post = Blog_Main.query.from_statement(text(str))
>>> print(post.statement)
select id from Blog_posts
雖然是Blog_Main,但是沒有實際query之前這語法還是會過,後面只要接了all、first…就會異常。
>>> post = Blog_Post.query.get(1)
>>> post
<POST> Flask
>>> post.id
1
>>> post = Blog_Post.query.with_entities(Blog_Post.blog_main_id).group_by(Blog_Post.blog_main_id)
>>> print(post.statement)
SELECT "Blog_Posts".blog_main_id
FROM "Blog_Posts" GROUP BY "Blog_Posts".blog_main_id
from sqlalchemy import func
>>> post = Blog_Post.query.with_entities(Blog_Post.blog_main_id).group_by(Blog_Post.blog_main_id).having(func.count(Blog_Post.blog_main_id)>1)
>>> print(post.statement)
SELECT "Blog_Posts".blog_main_id
FROM "Blog_Posts" GROUP BY "Blog_Posts".blog_main_id
HAVING count("Blog_Posts".blog_main_id) > :count_1
>>> blog = Blog_Main.query.join(Blog_Main.posts)
>>> print(blog.statement)
SELECT "Blog_Main".id, "Blog_Main".blog_name, "Blog_Main".blog_descri, "Blog_Main".blog_create_date, "Blog_Main".blog_cover_url, "Blog_Main".author
FROM "Blog_Main" JOIN "Blog_Posts" ON "Blog_Main".id = "Blog_Posts".blog_main_id
>>> blog = Blog_Main.query.join(Blog_Post)
>>> print(blog.statement)
SELECT "Blog_Main".id, "Blog_Main".blog_name, "Blog_Main".blog_descri, "Blog_Main".blog_create_date, "Blog_Main".blog_cover_url, "Blog_Main".author
FROM "Blog_Main" JOIN "Blog_Posts" ON "Blog_Main".id = "Blog_Posts".blog_main_id
下面是故意以沒有fk值的model來做join
>>> blog = Blog_Main.query.join(Role)
Traceback (most recent call last):
File "D:\proPycharm\app_blog\venv\lib\site-packages\sqlalchemy\orm\query.py", line 2386, in _join_to_left
clause, right, onclause, isouter=outerjoin, full=full)
>>> blog = Blog_Main.query.join(Blog_Post, Blog_Main.id==Blog_Post.blog_main_id)
>>> print(blog.statement)
SELECT "Blog_Main".id, "Blog_Main".blog_name, "Blog_Main".blog_descri, "Blog_Main".blog_create_date, "Blog_Main".blog_cover_url, "Blog_Main".author
FROM "Blog_Main" JOIN "Blog_Posts" ON "Blog_Main".id = "Blog_Posts".blog_main_id
>>> blog = Blog_Main.query.filter_by(author=1).subquery()
>>> user = UserRegister.query.join(blog, UserRegister.blog_mains)
>>> print(user.statement)
SELECT "UserRgeisters".id, "UserRgeisters".username,
"UserRgeisters".email, "UserRgeisters".password_hash,
"UserRgeisters".confirm, "UserRgeisters".about_me,
"UserRgeisters".location, "UserRgeisters".gender,
"UserRgeisters".regist_date, "UserRgeisters".last_login
FROM "UserRgeisters" JOIN (SELECT "Blog_Main".id AS id,
"Blog_Main".blog_name AS blog_name, "Blog_Main".blog_descri AS blog_descri,
"Blog_Main".blog_create_date AS blog_create_date,
"Blog_Main".blog_cover_url AS blog_cover_url,
"Blog_Main".author AS author
FROM "Blog_Main"
WHERE "Blog_Main".author = :author_1) AS anon_1 ON "UserRgeisters".id = anon_1.author
或是利用一般的on的作法
user = UserRegister.query.join(blog, blog.c.author==UserRegister.id)
select_from
為主,不再是query
的物件
>>> user = UserRegister.query.select_from(Blog_Main).join(Blog_Main.user)
>>> print(user.statement)
SELECT "UserRgeisters".id, "UserRgeisters".username, "UserRgeisters".email, "UserRgeisters".password_hash,
"UserRgeisters".confirm, "UserRgeisters".about_me, "UserRgeisters".location, "UserRgeisters".gender,
"UserRgeisters".regist_date, "UserRgeisters".last_login
FROM "Blog_Main" JOIN "UserRgeisters" ON "UserRgeisters".id = "Blog_Main".author
sqlalchemy.orm.exc.MultipleResultsFound
sqlalchemy.orm.exc.NoResultFound
>>> user = UserRegister.query.filter_by(id=1).one()
>>> user
username:Shaoe.chen
>>> user = UserRegister.query.filter_by(id=11).one_or_none()
>>> type(user)
<class 'NoneType'>
>>> user = UserRegister.query.only_return_tuples(True)
>>> user
<flask_sqlalchemy.BaseQuery object at 0x0060CF30>
>>> for u in user:
... print(u)
...
(username:Shaoe.chen,)
>>> post = Blog_Post.query.order_by(Blog_Post.blog_main_id)
>>> print(post.statement)
SELECT "Blog_Posts".id, "Blog_Posts".title,
"Blog_Posts".body, "Blog_Posts".category_id,
"Blog_Posts".author_id, "Blog_Posts".blog_main_id,
"Blog_Posts".create_date, "Blog_Posts".edit_date,
"Blog_Posts".slug, "Blog_Posts".flag
FROM "Blog_Posts" ORDER BY "Blog_Posts".blog_main_id
>>> role = Role.query.filter("id=:id").params(id=1)
>>> print(role.statement)
SELECT roles.id, roles.name
FROM roles
WHERE id=:id
>>> role.all()
[Role is ADMIN]
>>> post = Blog_Post.query
>>> print(post.statement)
SELECT "Blog_Posts".id, "Blog_Posts".title,
"Blog_Posts".body, "Blog_Posts".category_id,
"Blog_Posts".author_id, "Blog_Posts".blog_main_id,
"Blog_Posts".create_date, "Blog_Posts".edit_date,
"Blog_Posts".slug, "Blog_Posts".flag
FROM "Blog_Posts"
>>> post = Blog_Post.query.with_entities(Blog_Post.id, Blog_Post.author_id)
>>> print(post.statement)
SELECT "Blog_Posts".id, "Blog_Posts".author_id
FROM "Blog_Posts"