1. 設為首頁   文化中國網歡迎您~!

          如何更好的使用flask-SQLAlchemy

          SQLAlchemy配置

          安裝flask-sqlalchemy,它是對SQLAlchemy基于flask的封裝,SQLAlchemy是python的orm框架并不是針對特定web的框架。

          配置數據庫

          這db初始化APP使用的db=SQLAlchemy(app)這種方式,這樣初始化的時候就會加載上下文環境,比如在交互式環境下,就可以直接User.query.get(1)查詢,還有一種初始化方式,db.init_app(app)這種方式在初始化的時候不會加載上下文環境,在交互式模式下操作數據庫時需要手動加載,例如

          with app.app_context():
          User.query.get(1)

          但是無論哪種方式,在視圖中進行數據查詢時,都不要手動加載上下文,因為在視圖中執行數據庫操作時,服務已經啟動,在視圖中上下文環境已經加載好了。

          SQLALCHEMY_ECHO = True 

          SQLALCHEMY_ECHO = True輸出效果

          在進行數據庫操作時輸出操作數據庫的日志,包括sql語句,方便調試,可以在測試環境打開線上關閉。

          新增數據

          添加單個數據

          db.session.add(user)

          添加多個數據,需傳遞一個列表

          db.session.add_all(users)

          基礎查詢

          User.query.get() 使用主鍵查詢,get()方法只能傳入主鍵

          User.query.get(1)
          Out[3]: <User 1>

          User.query.filter_by() 做一些簡單的查詢,只能使用單個條件或者and,稍微復雜的一點的類似!=者or則不支持

          User.query.filter_by(name='itcast').first()
          Out[5]: <User 1>

          User.query.filter() 相比filter_by則能做的更多,大部分的復雜查詢也都是用filter()來做

          db.session.query(User).all(),上面的查詢都是基于flask-sqlalchemy來進行的,這個是直接使用SQLAlchemy來操作數據庫

          offset、limit查詢

          offset從指定位置開始查詢,limit從開始位置返回指定個數數據,例如現在有個需求從第二個位置開始返回兩個用戶,

          User.query.offset(2).limit(2).all()
          Out[10]: [<User 4>, <User 5>]
          對應的sql就是
          select * from user_basic limit 2,2

          模糊查詢

          User.query.filter(User.name.startwith('itcast')).all()

          查詢用戶名是已itcast開頭的用戶,對應sql語法,name like 'itcast%' 還可以是User.name.endwith(''),對應sql中的語法是name like '%itcast'

          指定字段查詢

          在查詢數據庫是,通常不會直接select *進行查詢,需要指定字段,在flask-sqlalchemy中需要指定字段需要導入額外的方法來支持。

          from sqlalchemy.orm import load_only
          User.query.options(load_only(User.name,User.mobile))
          .filter(User.id == 1).first()
          Out[12]: <User 1>

          對應sql語句就就是

          select name, mobile from user where id=1 limit 1;

          使用聚合函數

          在flask-sqlalchemy使用聚合需要導入新函數,from sqlalchemy import func

          db.session.query(Relation.user_id, func.count(Relation.target_user_id))
          .group_by(Relation.user_id).all()
          Out[26]: [(1, 3)]

          列表中每個元組的第一位表示user_id,第二位表示聚合結果,上面查詢語句對應sql

          select user_id, target_user_id from user_relation group_by(user_id)

          關聯查詢

          1、使用外鍵關聯查詢

          建表的時候,我們將用戶的基本常用信息存儲在user_basic表中,另外的一些不常用的存儲在user_profile表中,在查詢的時候,如何通過user.profile就能查詢出profile表中存儲的信息呢?

          現在從表中指定外鍵,然后在主表指定額外的字段,進行關聯查詢,注意在從表設置外鍵是,里面傳的一定要是數據庫中真實的表名和字段名。

          id = db.Column('relation_id', db.Integer, db.ForeignKey('user_basic.user_id'),
          primary_key=True, doc='主鍵ID')

          在主表指定關聯字段

          profile = db.relationship("UserProfile", uselist=False)

          直接使用user.profile調用,以下是輸出結果

          2、使用primaryjoin關聯查詢

          在user_basic表中修改關聯字段屬性,db.relationship這種額外聲明的字段屬性,不對應數據庫表的字段,不是映射字段,只是為了方便進行關聯查詢的時候使用

          profile = db.relationship('UserProfile', 
          primaryjoin='User.id==foreign(UserProfile.id)', uselist=False)

          user.profile調用和上面的輸出結果一樣。

          3、指定字段關聯查詢

          上面的兩種方式都需要兩步才能查詢出結果,那么如何一次性查出呢。比如現在有一個需求需要查詢user_id=1用戶所關注用戶的信息,sql語句實現如下

          select a.user_id,b.user_name,b.mobile from user_relation as a 
          inner join user_basic as b on a.target_user_id=b.user_id
          where a.user_id=1;

          現在Relation表中增加關聯字段,

          user = db.relationship('User', 
          primaryjoin="Relation.target_user_id==foreign(User.id)")

          具體查詢語句如下

          執行效果

          從debug日志中,拿出SQLAlchemy生成的查詢語句和我們自己寫的看看是否一樣

          SELECT user_relation.relation_id AS user_relation_relation_id, user_basic.user_id AS user_basic_user_id, user_basic.user_name AS user_basic_user_name, user_relation.user_id AS user_relation_user_id, user_relation.target_user_id AS user_relation_target_user_id

          FROM user_relation INNER JOIN user_basic ON user_relation.target_user_id = user_basic.user_id

          WHERE user_relation.user_id = %(user_id_1)s,可以看出和之前寫的sql語句是一樣。

          私信我,可獲取此文章的python代碼包括model以及建表語句和測試數據,你們的關注是我創作的最大動力

          推薦閱讀:iphone8長寬高
          好运来 www.lnkqxx.com:太仆寺旗| www.shnanyabxg.com:旺苍县| www.686302.com:丰都县| www.materialhandler.net:上蔡县| www.oushunuxe.com:沙雅县| www.daikaisu.com:波密县| www.vsexpesenok.net:洛隆县| www.poeticasvisuais.com:斗六市| www.626037.com:那坡县| www.phuengoat.com:九台市| www.hbtw.net:天气| www.spiritspace.net:雅安市| www.airotours.com:高密市| www.businessptr.com:阿城市| www.alshamdc.com:长白| www.employerlawblog.com:乐平市| www.kpt555.com:云阳县| www.penghancurbatuempedu.com:五河县| www.gythe.cn:太康县| www.bromoijenvacation.com:定州市| www.accwangxiao.com:新民市| www.nederlandsefilms.com:鹰潭市| www.lx9188.com:锡林浩特市| www.aaaago.com:济宁市| www.warnarumah.net:安福县| www.02art.com:隆化县| www.dj-ruki.com:闻喜县| www.bash4guild.com:彰化市| www.name-com.com:桂平市| www.dominic-paul.com:郧西县| www.buchuebersetzungen.com:获嘉县| www.hao-jiazheng.com:扎兰屯市| www.shnanyabxg.com:永靖县| www.ykfone.com:新兴县| www.lan-tour.com:香河县| www.sxsz.org:丹东市| www.bestkitchenkniveslist.com:彰化县| www.jsxyybj.com:娱乐| www.cs98ktv.com:抚顺市| www.fionatate.com:罗田县| www.5niu5.com:石城县| www.sincerely-0501.com:五指山市| www.tudoparacelular.com:迭部县| www.eschervictoria.com:清河县| www.ziyuangx8.com:介休市| www.genesis-int-corp.com:中阳县| www.xx3588.com:墨竹工卡县| www.hg19345.com:台江县| www.ph581.com:邹平县| www.novel199.com:沛县| www.024wanlikt.com:关岭| www.rlphw.cn:道孚县| www.huanxiangtong.com:金川县| www.jamesstephenshurling.com:贺兰县| www.yz-tygy.com:汉寿县| www.kmnwr.cn:车致| www.qdchaoqun88.com:紫金县| www.andcamera.com:牡丹江市| www.sf123cq.com:元谋县| www.voxpopolo.com:隆尧县| www.face53.com:廊坊市| www.abdulkafi.com:闻喜县| www.xyyueqi.com:武强县| www.ykw100.com:长兴县| www.ynunxjlx.com:桐乡市| www.baixiaojiecaitu88.com:江陵县| www.pppmiami.org:洛阳市| www.seafishingtackle.net:随州市| www.jamesstephenshurling.com:金堂县| www.sap-rope.com:苍梧县| www.sortpix.com:资阳市| www.glassfart.com:呼和浩特市| www.khxrw.cn:日喀则市| www.crowwebdesign.com:资阳市| www.hearthemlive.com:二连浩特市| www.kljlw.cn:三亚市| www.patricshawbeauty.com:陆川县| www.culasse-moteur.com:增城市| www.websaran.com:门头沟区| www.meimeihaose.com:老河口市| www.blgzs88.com:乌苏市| www.np755.com:肥乡县| www.autocity-curacao.com:平陆县| www.whxblaw.com:罗平县|