最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python ORM框架SQLAlchemy學(xué)習(xí)筆記之?dāng)?shù)據(jù)添加和事務(wù)回滾介紹

 更新時(shí)間:2014年06月10日 10:52:11   作者:  
這篇文章主要介紹了Python ORM框架SQLAlchemy學(xué)習(xí)筆記之?dāng)?shù)據(jù)添加和事務(wù)回滾介紹,需要的朋友可以參考下

1. 添加一個(gè)新對(duì)象

前面介紹了映射到實(shí)體表的映射類(lèi)User,如果我們想將其持久化(Persist),那么就需要將這個(gè)由User類(lèi)建立的對(duì)象實(shí)例添加到我們先前創(chuàng)建的Session會(huì)話(huà)實(shí)例中:

復(fù)制代碼 代碼如下:

ed_user = User('ed', 'Ed Jones', 'edspassword')
session.add(ed_user)

上面兩段代碼執(zhí)行完后對(duì)象持久化了么?你或許會(huì)興沖沖的跑去數(shù)據(jù)庫(kù)里查看,結(jié)果卻失望而歸——數(shù)據(jù)庫(kù)里什么都沒(méi)有。為什么呢?因?yàn)镾QLAlchemy采取的是Lazyload策略,也就是說(shuō)現(xiàn)在這個(gè)對(duì)象被標(biāo)記為Pending準(zhǔn)備狀態(tài),但沒(méi)有執(zhí)行任何可能導(dǎo)致數(shù)據(jù)庫(kù)變化的SQL語(yǔ)句。那么什么時(shí)候會(huì)執(zhí)行SQL語(yǔ)句并真正持久化呢?這個(gè)要等SQLAlchemy覺(jué)得需要的時(shí)候,比如我們現(xiàn)在查詢(xún)這個(gè)對(duì)象、對(duì)象的一個(gè)屬性或者顯式的調(diào)用flush方法,這時(shí)候SQLAlchemy覺(jué)得它“是時(shí)候”或者“不得不”執(zhí)行SQL數(shù)據(jù)庫(kù)查詢(xún)以便于把標(biāo)記為Pending的數(shù)據(jù)寫(xiě)入數(shù)據(jù)庫(kù)表中了。假如這時(shí)候你執(zhí)行的獲取對(duì)象、對(duì)象屬性或者類(lèi)似的操作,SQLAlchemy在執(zhí)行完SQL語(yǔ)句后會(huì)將你所要查詢(xún)的數(shù)據(jù)反饋給你。


為了更好的說(shuō)明這一點(diǎn),這里舉一個(gè)例子,這里涉及到我們第一個(gè)查詢(xún)示例,我們調(diào)用了Query對(duì)象來(lái)幫助我們完成這些,比如這里我們獲取剛剛持久化的用戶(hù)ed,我們通過(guò)“過(guò)濾(filter by)”的方式來(lái)查詢(xún)用戶(hù)名為ed的用戶(hù),當(dāng)然我們只需要一個(gè)ed,假如有多個(gè)重名的ed的話(huà),查詢(xún)將會(huì)返回所有叫ed的記錄集列表,我們就選擇第一個(gè)ed吧(first)。

復(fù)制代碼 代碼如下:

>>> our_user = session.query(User).filter_by(name='ed').first()
BEGIN (implicit)
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('ed', 'Ed Jones', 'edspassword')
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 = ?
 LIMIT ? OFFSET ?
('ed', 1, 0)
>>> our_user
<User('ed','Ed Jones', 'edspassword')>

可以看到上面的查詢(xún)語(yǔ)句返回了一個(gè)User的實(shí)例,而這個(gè)實(shí)例恰恰是我們先前持久化的。同時(shí)由于我們指定了引擎的echo=True,所以再執(zhí)行查詢(xún)時(shí)輸出了SQL語(yǔ)句,我們注意到除了普通的SELECT外,還有額外的INSERT語(yǔ)句,而INSERT處理的就是我們剛剛通過(guò)session.add()持久化標(biāo)記為Pending的對(duì)象,也就是說(shuō)你在實(shí)際操作持久化數(shù)據(jù)時(shí)才會(huì)由延遲加載(lazyload)真正觸發(fā)數(shù)據(jù)庫(kù)操作。

實(shí)際上Session查詢(xún)反饋給我們的User對(duì)象和我們剛剛持久化的對(duì)象是同一個(gè)對(duì)象,通過(guò)下面的代碼可以檢驗(yàn):

復(fù)制代碼 代碼如下:

>>> ed_user is our_user
True

實(shí)際上這里ORM的操作概念有點(diǎn)類(lèi)似于標(biāo)識(shí)映射(identity map),也就是說(shuō)在實(shí)體數(shù)據(jù)庫(kù)之前架設(shè)一張標(biāo)識(shí)映射表,可以看作緩存表的一種,任何存儲(chǔ)數(shù)據(jù)庫(kù)的對(duì)象會(huì)事先停留在這張表上,如果我們要查詢(xún)一個(gè)對(duì)象,將事先查詢(xún)這張標(biāo)識(shí)映射表,如果這個(gè)對(duì)象存在則直接取出,否則就會(huì)查詢(xún)實(shí)體數(shù)據(jù)庫(kù),我覺(jué)得這個(gè)有點(diǎn)像緩存的作用,可以這么理解吧。


一旦一個(gè)帶有獨(dú)一無(wú)二的主鍵的對(duì)象被Session持久化了,所有使用該主鍵在同一Session上查詢(xún)的對(duì)象將是同一個(gè)Python對(duì)象。當(dāng)然對(duì)于在這個(gè)會(huì)話(huà)中持久化另外一個(gè)具有相同主鍵的對(duì)象將會(huì)拋出異常錯(cuò)誤(主鍵不能重復(fù))。

如果我們想一次性添加多個(gè)對(duì)象到Session中可以調(diào)用add_all():

復(fù)制代碼 代碼如下:

>>> session.add_all([
...     User('wendy', 'Wendy Williams', 'foobar'),
...     User('mary', 'Mary Contrary', 'xxg527'),
...     User('fred', 'Fred Flinstone', 'blah')])

下面再談?wù)勑薷?,假如Ed覺(jué)得他的密碼不太安全,決定修改,可以直接這么做:
復(fù)制代碼 代碼如下:

>>> ed_user.password = 'f8s7ccs'

同樣的道理,這個(gè)改動(dòng)不會(huì)立即反映到數(shù)據(jù)庫(kù)里,當(dāng)然Session意識(shí)到你要修改Ed的密碼,它會(huì)暫時(shí)緩沖這個(gè)改動(dòng),我們可以通過(guò)dirty方法了解到我們的改動(dòng):
復(fù)制代碼 代碼如下:

>>> session.dirty
IdentitySet([<User('ed','Ed Jones', 'f8s7ccs')>])

同樣的我們可以通過(guò)new方法“窺看”到先前用add_all()持久化的對(duì)象列表:
復(fù)制代碼 代碼如下:

>>> session.new 
IdentitySet([<User('wendy','Wendy Williams', 'foobar')>,
<User('mary','Mary Contrary', 'xxg527')>,
<User('fred','Fred Flinstone', 'blah')>])

當(dāng)然這些改動(dòng)都沒(méi)有真正反饋到數(shù)據(jù)庫(kù)里,相當(dāng)于都被ORM緩沖了。接下來(lái)我們可以顯式的調(diào)用commit()來(lái)告訴Session:“我們目前就添加或者改動(dòng)這么多可以提交數(shù)據(jù)庫(kù)了”:
復(fù)制代碼 代碼如下:

>>> session.commit()
UPDATE users SET password=? WHERE users.id = ?
('f8s7ccs', 1)
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('wendy', 'Wendy Williams', 'foobar')
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('mary', 'Mary Contrary', 'xxg527')
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('fred', 'Fred Flinstone', 'blah')
COMMIT

于是剛才緩沖的數(shù)據(jù)或者變更全部被作為事務(wù)一次性flush到數(shù)據(jù)庫(kù)了,通過(guò)輸出的SQL語(yǔ)句我們也可以看出來(lái)。

這個(gè)操作完成后被會(huì)話(huà)(Session)引用的數(shù)據(jù)庫(kù)連接資源將被回收到連接池中,接下來(lái)的對(duì)于這個(gè)Session的任何操作將會(huì)觸發(fā)一個(gè)新的事務(wù)(Transaction),當(dāng)然會(huì)再次和連接池申請(qǐng)獲得數(shù)據(jù)庫(kù)連接資源。

之前文章介紹到Ed的User對(duì)象的id為None,現(xiàn)在讓我們來(lái)看看吧:

復(fù)制代碼 代碼如下:

>>> ed_user.id
BEGIN (implicit)
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.id = ?
(1,)
1

除了由于echo=True導(dǎo)致輸出的SQL語(yǔ)句,看看是不是有了值,值為1。

無(wú)論是立即(commit、flush)或者通過(guò)“首次訪(fǎng)問(wèn)加載(load-on-first-access)”,在Session在數(shù)據(jù)庫(kù)插入一條新記錄后,所有新生成的標(biāo)識(shí)和數(shù)據(jù)庫(kù)生成的默認(rèn)值對(duì)于實(shí)例來(lái)說(shuō)才可以被訪(fǎng)問(wèn)到。

當(dāng)調(diào)用了commit()以后,SQLAlchemy將會(huì)刷新當(dāng)前事務(wù)的所有數(shù)據(jù)到數(shù)據(jù)庫(kù)里。

2. 事務(wù)回滾

本文以及同系列的文章是以自己的想法翻譯的,不當(dāng)之處還請(qǐng)指正,不做權(quán)威依據(jù)。好了,下面我還是簡(jiǎn)單介紹一下事務(wù)回滾吧,其實(shí)這個(gè)和數(shù)據(jù)庫(kù)的事務(wù)回滾一個(gè)意思,就是我們做錯(cuò)事后要撤消之前的變更。

因?yàn)镾ession是作為事務(wù)(transaction)來(lái)工作的,所以我們可以回滾(roll back)先前所做的更改。接下來(lái)讓我們做兩個(gè)稍后會(huì)被撤銷(xiāo)(回滾)的更改,第一個(gè)是修改ed_user.name:

復(fù)制代碼 代碼如下:

>>> ed_user.name = 'Edwardo'

第二個(gè)是增加一個(gè)“不期望”的用戶(hù)fake_user:
復(fù)制代碼 代碼如下:

>>> fake_user = User('fakeuser', 'Invalid', '12345')
>>> session.add(fake_user)

查詢(xún)當(dāng)前會(huì)話(huà),我們可以看到這兩個(gè)變更已經(jīng)被flush到當(dāng)前事務(wù)里了:
復(fù)制代碼 代碼如下:

>>> session.query(User).filter(User.name.in_(['Edwardo', 'fakeuser'])).all()
UPDATE users SET name=? WHERE users.id = ?
('Edwardo', 1)
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
('fakeuser', 'Invalid', '12345')
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 IN (?, ?)
('Edwardo', 'fakeuser')
[<User('Edwardo','Ed Jones', 'f8s7ccs')>, <User('fakeuser','Invalid', '12345')>]

好吧,接下來(lái)是見(jiàn)證奇跡的時(shí)刻,我們回滾(rolling back)事務(wù):
復(fù)制代碼 代碼如下:

>>> session.rollback()
ROLLBACK
>>> ed_user.name
BEGIN (implicit)
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.id = ?
(1,)
u'ed'
>>> fake_user in session
False


我們可以看到ed_user的名字變回ed,并且我們不期望的用戶(hù)fake_user被“踢出”會(huì)話(huà)(Session)了。

最后,我們可以查詢(xún)一下用戶(hù)名在['ed', 'fakeuser']范圍的用戶(hù),確保我們的更改是有效的:

復(fù)制代碼 代碼如下:

>>> session.query(User).filter(User.name.in_(['ed', 'fakeuser'])).all()
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 IN (?, ?)
('ed', 'fakeuser')
[<User('ed','Ed Jones', 'f8s7ccs')>]

好了,今天就到這里,今天我們講解了添加對(duì)象和事務(wù)回滾,或多或少穿插了些簡(jiǎn)單的查詢(xún),接下來(lái)我們會(huì)介紹較為復(fù)雜一些的查詢(xún)語(yǔ)句,敬請(qǐng)期待!

相關(guān)文章

  • python實(shí)現(xiàn)將json多行數(shù)據(jù)傳入到mysql中使用

    python實(shí)現(xiàn)將json多行數(shù)據(jù)傳入到mysql中使用

    這篇文章主要介紹了python實(shí)現(xiàn)將json多行數(shù)據(jù)傳入到mysql中使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • python如何在文件中部插入信息

    python如何在文件中部插入信息

    這篇文章主要介紹了python如何在文件中部插入信息問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • python實(shí)現(xiàn)敲木魚(yú)加功德包含加音效和敲擊動(dòng)作(附demo)

    python實(shí)現(xiàn)敲木魚(yú)加功德包含加音效和敲擊動(dòng)作(附demo)

    敲木魚(yú)加功德是一款很火的動(dòng)畫(huà),本文主要介紹了python實(shí)現(xiàn)敲木魚(yú)加功德包含加音效和敲擊動(dòng)作,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-11-11
  • python爬蟲(chóng)自動(dòng)創(chuàng)建文件夾的功能

    python爬蟲(chóng)自動(dòng)創(chuàng)建文件夾的功能

    這篇文章主要介紹了python爬蟲(chóng)自動(dòng)創(chuàng)建文件夾的功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-08-08
  • 使用Python自制一個(gè)回收站清理器

    使用Python自制一個(gè)回收站清理器

    經(jīng)常筆記本電腦的回收站存儲(chǔ)了很多的文件,需要打開(kāi)回收站全部選中進(jìn)行清理。這篇文章將使用Python自制一個(gè)回收站清理器,需要的可以參考一下
    2023-03-03
  • Python中os模塊的12種用法總結(jié)

    Python中os模塊的12種用法總結(jié)

    OS?(?Operating?System?操作系統(tǒng)?)?操作系統(tǒng)模塊;它是屬于python的標(biāo)準(zhǔn)庫(kù),常用于處理文件和目錄(文件夾)的操作。本文為大家總結(jié)了這個(gè)模塊的12種用法,希望有所幫助
    2022-08-08
  • 利用Python復(fù)制文件的9種方法總結(jié)

    利用Python復(fù)制文件的9種方法總結(jié)

    這篇文章主要給大家總結(jié)介紹了關(guān)于利用Python復(fù)制文件的9種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Python具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Python定時(shí)任務(wù)工具之APScheduler使用方式

    Python定時(shí)任務(wù)工具之APScheduler使用方式

    APScheduler (advanceded python scheduler)是一款Python開(kāi)發(fā)的定時(shí)任務(wù)工具。這篇文章主要介紹了Python定時(shí)任務(wù)工具--APScheduler的使用方式,需要的朋友可以參考下
    2019-07-07
  • Pytorch實(shí)現(xiàn)基于CharRNN的文本分類(lèi)與生成示例

    Pytorch實(shí)現(xiàn)基于CharRNN的文本分類(lèi)與生成示例

    今天小編就為大家分享一篇Pytorch實(shí)現(xiàn)基于CharRNN的文本分類(lèi)與生成示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-01-01
  • Python中使用Beautiful Soup庫(kù)的超詳細(xì)教程

    Python中使用Beautiful Soup庫(kù)的超詳細(xì)教程

    這篇文章主要介紹了Python中使用Beautiful Soup庫(kù)的超詳細(xì)教程,示例代碼基于Python2.x版本,極力推薦!需要的朋友可以參考下
    2015-04-04

最新評(píng)論

榕江县| 公主岭市| 米易县| 宜都市| 连城县| 会泽县| 盘锦市| 玉门市| 承德市| 永安市| 开阳县| 巴青县| 东城区| 郎溪县| 凤凰县| 射洪县| 简阳市| 香格里拉县| 桦南县| 尤溪县| 阿勒泰市| 司法| 东山县| 哈尔滨市| 清原| 克拉玛依市| 宝丰县| 鄢陵县| 仪征市| 来凤县| 龙游县| 兴宁市| 莒南县| 慈溪市| 五家渠市| 通化县| 梁山县| 农安县| 忻城县| 万山特区| 广河县|