成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Flask Web Development —— 數(shù)據(jù)庫(kù)(中)

April / 3327人閱讀

摘要:關(guān)系關(guān)系數(shù)據(jù)庫(kù)通過(guò)使用關(guān)系在不同的表中建立連接。以下部分將介紹最常見(jiàn)的數(shù)據(jù)庫(kù)操作。如果數(shù)據(jù)庫(kù)已存在函數(shù)不會(huì)重新創(chuàng)建或更新數(shù)據(jù)庫(kù)表。到目前為止對(duì)象只存于中,他們還沒(méi)有被寫(xiě)入數(shù)據(jù)庫(kù)。數(shù)據(jù)庫(kù)會(huì)話也叫事務(wù)。刪除行數(shù)據(jù)庫(kù)會(huì)話同樣有方法。

7、關(guān)系

關(guān)系數(shù)據(jù)庫(kù)通過(guò)使用關(guān)系在不同的表中建立連接。圖像5-1的關(guān)系圖表達(dá)了用戶和用戶角色之間的簡(jiǎn)單關(guān)系。這個(gè)角色和用戶是一對(duì)多關(guān)系,因?yàn)橐粋€(gè)角色可以從屬于多個(gè)用戶,而一個(gè)用戶只能擁有一個(gè)角色。

示例5-3的模型類展示了圖像5-1中表達(dá)的一對(duì)多關(guān)系。

示例5-3. hello.py:關(guān)系

class Role(db.Model): 
    # ...
    users = db.relationship("User", backref="role")

class User(db.Model): 
    # ...
    role_id = db.Column(db.Integer, db.ForeignKey("roles.id"))

就像圖像5-1中看到的那樣,關(guān)系通過(guò)使用外鍵來(lái)連接兩行。添加給User模型的role_id列被定義為外鍵,且建立關(guān)系。db.ForeignKey()的參數(shù)roles.id指定的列應(yīng)該理解為在roles表的行中持有id值的列。

添加到Role模型的users屬性表現(xiàn)了關(guān)系的面向?qū)ο蟮挠^點(diǎn)。給定Role類的實(shí)例,users屬性會(huì)返回一組連接到該角色的用戶。指定給db.relationship()的第一個(gè)參數(shù)表明模型中關(guān)系的另一邊。如果類還未定義,這個(gè)模型可以作為字符串提供。

  

注意:之前在segmentdefault中遇到的問(wèn)題,后來(lái)粗略閱讀了SQLAlchemy的源碼。ForeignKey類的column接收三種類型的參數(shù),一種是“模型名.屬性名”;一種是“表名.列名”,最后一種沒(méi)看明白,下次試著用一下。

db.relationship()backref參數(shù)通過(guò)給User模型增加role屬性來(lái)定義反向關(guān)系。這個(gè)屬性可以替代role_id訪問(wèn)Role模型,是作為對(duì)象而不是外鍵。

大多數(shù)情況下db.relationship()可以定位自己的外鍵關(guān)系,但是有時(shí)候不能確定哪個(gè)列被用作外鍵。例如,如果User模型有兩個(gè)或更多列被定義為Role的外鍵,SQLAlchemy將不知道使用兩個(gè)中的哪一個(gè)。每當(dāng)外鍵配置模棱兩可的時(shí)候,就必須使用額外參數(shù)db.relationship()。表格5-4列出一些常用配置選項(xiàng)用于定義關(guān)系。

表格5-4. 常用SQLAlchemy關(guān)系選項(xiàng)

  

建議:如果你有克隆在GitHub上的應(yīng)用程序,你現(xiàn)在可以運(yùn)行git checkout 5a來(lái)切換到這個(gè)版本的應(yīng)用程序。

除了一對(duì)多關(guān)系還有其他種類關(guān)系。一對(duì)一關(guān)系可以表述為前面描述的一對(duì)多關(guān)系,只要將db.relationship()中的uselist選項(xiàng)設(shè)置為False,“多”就變?yōu)椤耙弧绷恕?strong>多對(duì)一關(guān)系也可表示為將表反轉(zhuǎn)后的一對(duì)多關(guān)系,或表示為外鍵和db.relationship()定義在“多”那邊。最復(fù)雜的關(guān)系類型,多對(duì)多,需要一個(gè)被稱作關(guān)聯(lián)表的額外表。你將在第十二章學(xué)習(xí)多對(duì)多關(guān)系。

8、數(shù)據(jù)庫(kù)操作

根據(jù)圖像5-1的數(shù)據(jù)庫(kù)圖,模型已經(jīng)完全配置完且準(zhǔn)備好使用。學(xué)習(xí)怎樣使用模型的最好方式就是使用Python shell。以下部分將介紹最常見(jiàn)的數(shù)據(jù)庫(kù)操作。

8.1、創(chuàng)建表

首先要做的第一件事情就是指示Flask-SQLAlchemy基于模型類創(chuàng)建數(shù)據(jù)庫(kù)。db.create_all()函數(shù)會(huì)完成這些:

(venv) $ python hello.py shell 
>>> from hello import db
>>> db.create_all()

如果你檢查應(yīng)用程序目錄,你會(huì)發(fā)現(xiàn)名為data.sqlite的新文件,SQLite數(shù)據(jù)庫(kù)名在配置中給出。如果數(shù)據(jù)庫(kù)已存在db.create_all()函數(shù)不會(huì)重新創(chuàng)建或更新數(shù)據(jù)庫(kù)表。這會(huì)非常的不方便當(dāng)模型被修改且更改需要應(yīng)用到現(xiàn)有的數(shù)據(jù)庫(kù)時(shí)。更新現(xiàn)有的數(shù)據(jù)庫(kù)表的蠻力解決方案是先刪除舊的表:

>>> db.drop_all()
>>> db.create_all()

不幸的是,這種方法有個(gè)不受歡迎的副作用就是摧毀舊的數(shù)據(jù)庫(kù)中的所有數(shù)據(jù)。更新數(shù)據(jù)庫(kù)問(wèn)題的解決方案會(huì)在這章快結(jié)束的時(shí)候介紹。

8.2、插入行

下面的示例會(huì)創(chuàng)建新的角色和用戶:

>>> from hello import Role, User
>>> admin_role = Role(name="Admin")
>>> mod_role = Role(name="Moderator")
>>> user_role = Role(name="User")
>>> user_john = User(username="john", role=admin_role) 
>>> user_susan = User(username="susan", role=user_role) 
>>> user_david = User(username="david", role=user_role)

模型的構(gòu)造函數(shù)接受模型屬性的初始值作為關(guān)鍵字參數(shù)。注意,甚至可以使用role屬性,即使它不是一個(gè)真正的數(shù)據(jù)庫(kù)列,而是一對(duì)多關(guān)系的高級(jí)表示。這些新對(duì)象的id屬性沒(méi)有顯式設(shè)置:主鍵由Flask-SQLAlchemy來(lái)管理。到目前為止對(duì)象只存于Python中,他們還沒(méi)有被寫(xiě)入數(shù)據(jù)庫(kù)。因?yàn)樗麄兊?b>id值尚未分配:

>>> print(admin_role.id) None
>>> print(mod_role.id) None
>>> print(user_role.id) None

修改數(shù)據(jù)庫(kù)的操作由Flask-SQLAlchemy提供的db.session數(shù)據(jù)庫(kù)會(huì)話來(lái)管理。準(zhǔn)備寫(xiě)入到數(shù)據(jù)庫(kù)中的對(duì)象必須添加到會(huì)話中:

>>> db.session.add(admin_role)
>>> db.session.add(mod_role)
>>> db.session.add(user_role)
>>> db.session.add(user_john)
>>> db.session.add(user_susan)
>>> db.session.add(user_david)

或,更簡(jiǎn)潔的:

>>> db.session.add_all([admin_role, mod_role, user_role,
...     user_john, user_susan, user_david])

為了寫(xiě)對(duì)象到數(shù)據(jù)庫(kù),需要通過(guò)它的commit()方法來(lái)提交會(huì)話:

>>> db.session.commit()

再次檢查id屬性;這個(gè)時(shí)候它們都已經(jīng)被設(shè)置好了:

>>> print(admin_role.id) 
1
>>> print(mod_role.id)
2
>>> print(user_role.id) 
3
  

注:db.session數(shù)據(jù)庫(kù)會(huì)話和第四章討論的Flask會(huì)話沒(méi)有任何聯(lián)系。數(shù)據(jù)庫(kù)會(huì)話也叫事務(wù)。

數(shù)據(jù)庫(kù)會(huì)話在數(shù)據(jù)庫(kù)一致性上是非常有用的。提交操作會(huì)原子性地將所有添加到會(huì)話中的對(duì)象寫(xiě)入數(shù)據(jù)庫(kù)。如果在寫(xiě)入的過(guò)程發(fā)生錯(cuò)誤,會(huì)將整個(gè)會(huì)話丟棄。如果你總是在一個(gè)會(huì)話提交相關(guān)修改,你必須保證避免因部分更新導(dǎo)致的數(shù)據(jù)庫(kù)不一致的情況。

  

注:數(shù)據(jù)庫(kù)會(huì)話也可以回滾。如果調(diào)用db.session.rollback(),任何添加到數(shù)據(jù)庫(kù)會(huì)話中的對(duì)象都會(huì)恢復(fù)到它們?cè)?jīng)在數(shù)據(jù)庫(kù)中的狀態(tài)。

8.3、修改行

數(shù)據(jù)庫(kù)會(huì)話中的add()方法同樣可以用于更新模型。繼續(xù)在同一shell會(huì)話中,下面的示例重命名“Admin”角色為“Administrator”:

>>> admin_role.name = "Administrator"
>>> db.session.add(admin_role)
>>> db.session.commit()
  

注意:不過(guò)貌似我們?cè)谧龈虏僮鞯臅r(shí)候都不使用db.session.add(),而是直接使用db.session.commit()來(lái)提交事務(wù)。

8.4、刪除行

數(shù)據(jù)庫(kù)會(huì)話同樣有delete()方法。下面的示例從數(shù)據(jù)庫(kù)中刪除“Moderator”角色:

>>> db.session.delete(mod_role)
>>> db.session.commit()

注意刪除,和插入更新一樣,都是在數(shù)據(jù)庫(kù)會(huì)話提交后執(zhí)行。

8.5、返回行

Flask-SQLAlchemy為每個(gè)模型類創(chuàng)建一個(gè)query對(duì)象。最基本的查詢模型是返回對(duì)應(yīng)的表的全部?jī)?nèi)容:

>>> Role.query.all()
[, ]
>>> User.query.all()
[, , ]

使用過(guò)濾器可以配置查詢對(duì)象去執(zhí)行更具體的數(shù)據(jù)庫(kù)搜索。下面的例子查找所有被分配“User”角色的用戶:

>>> User.query.filter_by(role=user_role).all()
[, ]

對(duì)于給定的查詢還可以檢查SQLAlchemy生成的原生SQL查詢,并將查詢對(duì)象轉(zhuǎn)換為一個(gè)字符串:

>>> str(User.query.filter_by(role=user_role))
"SELECT users.id AS users_id, users.username AS users_username,
users.role_id AS users_role_id FROM users WHERE :param_1 = users.role_id"

如果你退出shell會(huì)話,在前面的示例中創(chuàng)建的對(duì)象將不能作為Python對(duì)象而存在,但可繼續(xù)作為行記錄存在各自的數(shù)據(jù)庫(kù)表中。如果你開(kāi)始一個(gè)全新的shell會(huì)話,你必須從它們的數(shù)據(jù)庫(kù)行中重新創(chuàng)建Python對(duì)象。下面的示例執(zhí)行查詢來(lái)加載名字為“User”的用戶角色。

>>> user_role = Role.query.filter_by(name="User").first()

過(guò)濾器如filter_by()通過(guò)query對(duì)象來(lái)調(diào)用,且返回經(jīng)過(guò)提煉后的query。多個(gè)過(guò)濾器可以依次調(diào)用直到需要的查詢配置結(jié)束為止。

表格5-5展示一些查詢中常用的過(guò)濾器。完整的列表參閱SQLAlchemy文檔。

表格5-5.常用SQLAlchemy查詢過(guò)濾器

在需要的過(guò)濾器已經(jīng)全部運(yùn)用于query后,調(diào)用all()會(huì)觸發(fā)query執(zhí)行并返回一組結(jié)果,但是除了all()以外還有其他方式可以觸發(fā)執(zhí)行。表格5-6.展示其他查詢執(zhí)行方法。

表格5-6.常用SQLAlchemy查詢執(zhí)行器

關(guān)系的原理類似于查詢。下面的示例從兩邊查詢角色和用戶之間的一對(duì)多關(guān)系:

>>> users = user_role.users
>>> users
[, ]
>>> users[0].role

此處的user_role.users查詢有點(diǎn)小問(wèn)題。當(dāng)user_role.users表達(dá)式在內(nèi)部調(diào)用all()時(shí)通過(guò)隱式查詢執(zhí)行來(lái)返回用戶的列表。因?yàn)椴樵儗?duì)象是隱藏的,是不可能通過(guò)附加查詢過(guò)濾器進(jìn)一步提取出來(lái)。在這個(gè)特定的例子中,它可能是用于按字母排列順序返回用戶列表。在示例5-4中,被lazy = "dynamic"參數(shù)修改過(guò)的關(guān)系配置的查詢是不會(huì)自動(dòng)執(zhí)行的。

示例5-4. app/models.py:動(dòng)態(tài)關(guān)系

class Role(db.Model): 
    # ...
    users = db.relationship("User", backref="role", lazy="dynamic") 
    # ...

用這種方式配置關(guān)系,user_roles.user查詢還沒(méi)有執(zhí)行,所以可以給它增加過(guò)濾器:

>>> user_role.users.order_by(User.username).all()
[, ]
>>> user_role.users.count()
2

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/37470.html

相關(guān)文章

  • Flask Web Development —— Web表單(上)

    摘要:每個(gè)表單域都可以連接到一個(gè)或多個(gè)是一個(gè)用于檢查用戶提交的輸入是否合法的函數(shù)。表單域構(gòu)造函數(shù)的第一個(gè)參數(shù)是一個(gè),在渲染表單到時(shí)會(huì)使用。驗(yàn)證確保提交的表單域不為空。表單域驗(yàn)證都是直接從包中導(dǎo)入。表格展示了一組支持的標(biāo)準(zhǔn)表單域。 第二章中介紹的request對(duì)象公開(kāi)了所有客戶端發(fā)送的請(qǐng)求信息。特別是request.form可以訪問(wèn)POST請(qǐng)求提交的表單數(shù)據(jù)。 盡管Flask的request...

    CODING 評(píng)論0 收藏0
  • [分享] Flask 網(wǎng)絡(luò)開(kāi)發(fā)經(jīng)典書(shū)籍: Flask Web Development

    摘要:他和妻子四個(gè)孩子兩只狗和一只貓共同生活在俄勒岡州波特蘭市。。還邀請(qǐng)他根據(jù)書(shū)的內(nèi)容,制作了兩個(gè)視頻教程。 showImg(http://img4.douban.com/lpic/s27205547.jpg); 這本書(shū)算是學(xué)習(xí)Flask的權(quán)威材料了,網(wǎng)上很多人都是推薦從這本書(shū)開(kāi)始學(xué)習(xí)。起初,作者在自己的博客發(fā)布了一個(gè)大型的Flask建站教程,在這個(gè)教程大受歡迎的基礎(chǔ)上,才與OReilly公...

    HmyBmny 評(píng)論0 收藏0
  • Flask Web Development —— 基本應(yīng)用程序結(jié)構(gòu)(上)

    摘要:注對(duì)于開(kāi)發(fā)者來(lái)說(shuō),傳給應(yīng)用程序構(gòu)造函數(shù)的參數(shù)是比較容易弄混淆的。在應(yīng)程序中定義路由的最便捷的方式是通過(guò)顯示定義在應(yīng)用程序?qū)嵗系难b飾器,注冊(cè)被裝飾的函數(shù)來(lái)作為一個(gè)路由。一個(gè)常見(jiàn)的模式是使用裝飾器來(lái)注冊(cè)函數(shù)作為一個(gè)事件處理程序。 在這一章,你將學(xué)習(xí)Flask應(yīng)用程序不同部分。同時(shí)你將編寫(xiě)和運(yùn)行你的第一個(gè)Flask web應(yīng)用程序。 1、初始化 在這章,你將學(xué)到Flask應(yīng)用程序的不...

    NusterCache 評(píng)論0 收藏0
  • Flask Web Development —— 基本應(yīng)用程序結(jié)構(gòu)(下)

    摘要:有兩類應(yīng)用級(jí)和請(qǐng)求級(jí)。一個(gè)響應(yīng)中非常重要的部分是狀態(tài)碼,默認(rèn)設(shè)置來(lái)指示請(qǐng)求已經(jīng)成功處理。重定向通常由響應(yīng)狀態(tài)碼注明并且重定向的由頭部的給出。因?yàn)檫@些變化,應(yīng)用程序獲得一組基本的命令行選項(xiàng)。運(yùn)行顯示可用信息在應(yīng)用程序上下文的內(nèi)部運(yùn)行一個(gè)。 5、請(qǐng)求-響應(yīng)循環(huán) 現(xiàn)在你已經(jīng)玩過(guò)一個(gè)基本的Flask應(yīng)用程序,你也許想要知道更多關(guān)于Flask如何施展魔力。下面章節(jié)描述了一些框架設(shè)計(jì)方面的特點(diǎn)。...

    caohaoyu 評(píng)論0 收藏0
  • Flask Web Development —— 大型應(yīng)用程序結(jié)構(gòu)(下)

    摘要:?jiǎn)卧獪y(cè)試這個(gè)應(yīng)用非常小以至于不需要太多的測(cè)試,但是作為示例會(huì)在示例中展示兩個(gè)簡(jiǎn)單的測(cè)試定義。示例單元測(cè)試編寫(xiě)好的測(cè)試使用的是來(lái)自于標(biāo)準(zhǔn)庫(kù)中標(biāo)準(zhǔn)的包。為了運(yùn)行單元測(cè)試,可以在腳本中增加一個(gè)自定義的命令。 4、啟動(dòng)腳本 頂層目錄中的manage.py文件用于啟動(dòng)應(yīng)用。這個(gè)腳本會(huì)在示例7-8中展示。 示例7-8. manage.py:?jiǎn)?dòng)腳本 #!/usr/bin/env python im...

    whidy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<