作者:Michael Bayer
譯者:謝路云
狀態(tài):翻譯中
SQLAlchem??y是一個Python語言的數(shù)據(jù)庫工具包和關(guān)系對象映射(ORM)系統(tǒng),始于2005年。從一開始,它就力求通過Python的數(shù)據(jù)庫API(即DBAPI)提供一種和關(guān)系數(shù)據(jù)庫交互的端對端系統(tǒng)。從早期的版本開始,SQLAlchemy的功能就吸引了很多人的注意力。它的主要特性包括能夠流暢的表達復(fù)雜的SQL查詢和對象映射,以及實現(xiàn)了"Unit of Work"模式來高度自動化的完成數(shù)據(jù)在數(shù)據(jù)庫中的持久化。
從一個渺小而粗糙的概念性實現(xiàn)開始,SQLAlchemy迅速經(jīng)歷了一系列蛻變和打磨。隨著用戶群的增長,內(nèi)部架構(gòu)和公共API也在不斷的迭代。到了2009年一月發(fā)布0.5版本之時,SQLAlchemy已經(jīng)在大量的生產(chǎn)環(huán)境中部署并證明了自己,并開始穩(wěn)定下來。0.6(2010年四月)和0.7(2011年五月)兩個版本對架構(gòu)和API的改進使我們成為了最高效和最穩(wěn)定的第三方庫。截至撰寫本文之時,大量不同領(lǐng)域的組織都在使用SQLAlchem??y。它已經(jīng)被大家認(rèn)可并事實上成為使用Python操作關(guān)系型數(shù)據(jù)庫的標(biāo)準(zhǔn)庫。
“數(shù)據(jù)庫抽象層”通常指的是一種用來和數(shù)據(jù)庫通訊并隱藏數(shù)據(jù)的存儲和查詢的大部分細(xì)節(jié)的系統(tǒng)。對這個詞的理解有時會走向一個極端,認(rèn)為這樣的系統(tǒng)應(yīng)該隱藏的不僅是所使用的關(guān)系數(shù)據(jù)庫的細(xì)節(jié),還應(yīng)該包括數(shù)據(jù)的關(guān)系結(jié)構(gòu),甚至不再關(guān)心底層的存儲機制是否是基于關(guān)系的。
對于ORM最常見的批評認(rèn)為以上就是這種工具的最主要目的——把關(guān)系數(shù)據(jù)庫“藏起來”,接管和數(shù)據(jù)庫的交互并將它們轉(zhuǎn)化為實現(xiàn)的細(xì)節(jié)。這種方式的核心意義在于將設(shè)計和查詢關(guān)系數(shù)據(jù)結(jié)構(gòu)的工作從開發(fā)者轉(zhuǎn)移到一個不透明的第三方庫中。
經(jīng)常和關(guān)系數(shù)據(jù)庫打交道的人都知道,這種認(rèn)識完全是不切實際的。關(guān)系結(jié)構(gòu)和SQL查詢都是功能性的,它們組成了一個應(yīng)用程序設(shè)計的核心。應(yīng)該如何在查詢中設(shè)計、組織和操作這些結(jié)構(gòu)不僅取決于要查詢哪些數(shù)據(jù),也取決于數(shù)據(jù)的結(jié)構(gòu)。如果連這些信息都要隱藏起來,那么也就根本沒有使關(guān)系數(shù)據(jù)庫的必要了。
既要滿足應(yīng)用程序屏蔽底層關(guān)系數(shù)據(jù)庫復(fù)雜性的期望,又要滿足使用關(guān)系數(shù)據(jù)庫所必要的繁復(fù),這種矛盾被稱為“對象-關(guān)系的阻抗不匹配”問題。SQLAlchem??y采用了一些新穎的方法來解決這個問題。
SQLAlchem??y的數(shù)據(jù)庫抽象層
SQLAlchem??y認(rèn)為開發(fā)人員必須要考慮他或者她的數(shù)據(jù)的關(guān)系形式。預(yù)判并隱藏數(shù)據(jù)庫schema和查詢的系統(tǒng)所設(shè)計的行為只會降低使用關(guān)系數(shù)據(jù)庫的必要性,進而導(dǎo)致阻抗不匹配所帶來的一系列經(jīng)典問題。(*)
但同時,這些行為的實現(xiàn)應(yīng)該也必須執(zhí)行在一個盡可能高的層次上。將一個對象模型和一個schema關(guān)聯(lián)起來并通過SQL語句將對象持久化是一項重復(fù)性極高的任務(wù)。使用工具來將這些任務(wù)自動化才能開發(fā)出更加簡潔、高效和強大的應(yīng)用程序。而手動實現(xiàn)這些操作的應(yīng)用程序所需的開發(fā)時間將會是它的數(shù)倍。(*)
因此,SQLAlchemy對自己的定位是一個工具包 ,這是為了強調(diào)開發(fā)者才是所有關(guān)系結(jié)構(gòu)以及這些結(jié)構(gòu)和應(yīng)用程序之間的聯(lián)系的設(shè)計者和構(gòu)造者,而不是第三方庫的盲目使用者。通過開放“關(guān)系”,SQLAlchem??y實現(xiàn)的理念是“不完全抽象”,(*)它不利開發(fā)者在應(yīng)用程序和關(guān)系數(shù)據(jù)庫之間自定義一個自動化的交互層。SQLAlchem??y的創(chuàng)新在于它能夠在不犧牲對關(guān)系數(shù)據(jù)庫的控制能力的前提下做到高度的自動化。
為了達到工具包這個目標(biāo),SQLAlchem??y將與數(shù)據(jù)庫交互的每一層都開放成為了一組成熟的API,這產(chǎn)生了兩種主要的交互方式,分別是核心層(Core)和對象關(guān)系映射層(ORM)。核心層負(fù)責(zé)和Python的數(shù)據(jù)庫API(DBAPI)的交互、拼接數(shù)據(jù)庫能夠理解的SQL語句并管理schema。這些功能都對應(yīng)著公開的API。
圖20.1的SQLAlchem??y的層圖
核心/ ORM SQLAlchem??y的分離一直是最本質(zhì)的特征,它既有優(yōu)點和缺點。目前在SQLAlchem??y的明確的核心導(dǎo)致ORM到關(guān)系數(shù)據(jù)庫映射類的屬性結(jié)構(gòu)被稱為一個Table ,而不是直接將其字符串表示在數(shù)據(jù)庫中的列名,產(chǎn)生一個SELECT查詢使用結(jié)構(gòu)稱為select ,而不是拼湊對象的屬性直接轉(zhuǎn)換成字符串聲明和接收結(jié)果行通過的的門面被稱為ResultProxy ,透明映射的select 每個結(jié)果行,而不是將數(shù)據(jù)直接從數(shù)據(jù)庫游標(biāo)一個用戶定義的對象。
核心元素的一個非常簡單的ORM為中心的應(yīng)用程序是不可見的。但是,為核心的精心整合的ORM,讓流動的過渡在ORM和核心之間的結(jié)構(gòu),更復(fù)雜的ORM為中心的應(yīng)用可以“向下移動”,以便處理與數(shù)據(jù)庫中的更多的水平或兩個具體和微調(diào)的方式,隨著形勢的需要。SQLAlchem??y的有成熟,核心API已經(jīng)變得不那么明確經(jīng)常使用的ORM繼續(xù)提供更復(fù)雜和更全面的圖案。但是,核心的可用性也是一個貢獻SQLAlchem??y的早期成功的,因為它允許早期的用戶來完成,更比可能的ORM仍在發(fā)展。
的ORM /核心方法的缺點是,指示必須穿越更多的步驟。Python的傳統(tǒng)的C實現(xiàn)有一個顯著的開銷處罰為獨立的功能調(diào)用,這是主要原因在運行時緩慢。傳統(tǒng)方法的改善這包括縮短呼叫通過重排鏈和內(nèi)聯(lián)與C代碼,并更換性能的關(guān)鍵領(lǐng)域。SQLAlchem??y的已經(jīng)花了多年使用這兩種方法提高性能。然而,越來越多的人接受的PyPy為Python解釋器可壁球余下的承諾性能問題,而不需要更換的多數(shù)SQLAlchem??y的內(nèi)部結(jié)構(gòu)與C語言代碼,PyPy大大剛剛在時間的調(diào)用鏈長通過減少的影響內(nèi)聯(lián)和編譯。
在該基地的SQLAlchem??y的是一個系統(tǒng)與數(shù)據(jù)庫進行交互,通過DBAPI。DBAPI本身是不是一個實際的庫,只有規(guī)范。因此,實現(xiàn)的DBAPI是可用于特別是目標(biāo)數(shù)據(jù)庫,如MySQL或PostgreSQL,或者特別是非DBAPI,如ODBC和JDBC數(shù)據(jù)庫適配器。
的DBAPI提出了兩方面的挑戰(zhàn)。第一是提供一種易于使用且功能齊全的門面周圍的DBAPI的最基本的使用模式。二是要處理的變量的性質(zhì)具體的DBAPI的實現(xiàn),以及底層的數(shù)據(jù)庫引擎。 方言系統(tǒng)
由DBAPI接口是非常簡單的。其核心部件DBAPI模塊本身,連接對象,并且將光標(biāo)對象的“光標(biāo)”數(shù)據(jù)庫中的說法表示的上下文中特別聲明以及其相關(guān)的結(jié)果。一個簡單的互動與這些對象連接和檢索數(shù)據(jù)庫中的數(shù)據(jù)如下:
連接= dbapi.connect(用戶=“用戶”,PW =“私服”,主機=“主機”)光標(biāo)通過connection.cursor()cursor.execute(“SELECT * FROM user_table,其中name =?”(“杰克”,))打印列在“結(jié)果:”,說明[0],描述在cursor.description]為排在cursor.fetchall():打印的“行”,行cursor.close()connection=close
SQLAlchem??y的創(chuàng)建一個門面周圍的經(jīng)典DBAPI談話?!包c進入這個門面是create_engine電話,組裝連接和配置信息。一個實例作為結(jié)果產(chǎn)生的Engine 。該對象,然后網(wǎng)關(guān)DBAPI,這本身是永遠(yuǎn)不會直接暴露。
對于簡單的語句執(zhí)行, Engine提供什么被稱為隱式執(zhí)行接口。本工作?獲取和關(guān)閉一個DBAPI連接和光標(biāo)在后臺處理:
引擎create_engine(“與postgresql :/ /用戶名:密碼:主機/數(shù)據(jù)庫”)結(jié)果engine.execute(“select * from表”)或打印result.fetchall(0)
SQLAlchemy的0.2的Connection對象補充說,提供的能力顯式地維護范圍的DBAPI連接:
康恩= engine.connect()專題專題查詢欄目位置(“select * from表”)或打印result.fetchall(0)conn.close()
返回的結(jié)果的execute方法的Engine 或Connection被稱為ResultProxy ,它提供了類似的DBAPI光標(biāo),但具有更豐富的接口行Engine ,Connection ,并ResultProxy對應(yīng)于DBAPI一個特定的模塊,例如DBAPI連接,和一個實例的一個特定的DBAPI光標(biāo)。
在幕后, Engine引用的對象所謂的Dialect 。Dialect是一個抽象的類存在許多實現(xiàn)的,每一個有針對性的在一個特定的的DBAPI /數(shù)據(jù)庫組合。創(chuàng)建一個ConnectionEngine代表將參照這個Dialect 可用于所有的決定,這取決于使用的目標(biāo)的DBAPI和數(shù)據(jù)庫可能具有不同的行為。
該Connection創(chuàng)建時,從一個倉庫,采購和維護的實際DBAPI連接被稱為一個Pool ,還與Engine相關(guān)聯(lián)的。Pool是負(fù)責(zé)創(chuàng)建新DBAPI連接的,通常情況下,他們保持經(jīng)常重復(fù)使用的內(nèi)存池。
在語句執(zhí)行期間,一個附加的對象被稱為ExecutionContext創(chuàng)建的Connection 。持續(xù)的對象點執(zhí)行的ResultProxy的整個生命周期。很顯然,那位同事是位多產(chǎn)教案,列表名單很大,所以教師選擇更先進的搜索,并增加了也可以提供作為一個特定的子類的一些DBAPI /數(shù)據(jù)庫的組合。
圖20.2說明了所有這些對象及其關(guān)系到每個以及其他的DBAPI組件。 圖20.2:發(fā)動機,連接,ResultProxy API 處理DBAPI變異
對于任務(wù)的管理DBAPI行為的變化,首先我們考慮問題的范圍。在DBAPI在第二版規(guī)范,目前,寫的是一個系列API定義,允許廣泛的變異程度行為,并留下一個不確定的領(lǐng)域。其結(jié)果是,現(xiàn)實生活中的DBAPIs表現(xiàn)出很大程度的變化在若干領(lǐng)域,包括當(dāng)Python如何unicode字符串是可以接受的,當(dāng)他們都沒有;“最后插入的ID” - 這是一個自動生成的主鍵可能是收購后的INSERT語句,以及如何綁定參數(shù)值可以指定和解釋。他們也有大量面向類型的特質(zhì)的行為,包括二進制處理,精度數(shù)值,日期,布爾和Unicode數(shù)據(jù)。
SQLAlchemy的接近允許在這兩個Dialect變化和ExecutionContext通過多層次的子類。如圖20.3所示Dialect之間的關(guān)系和ExecutionContext時用于與psycopg2的方言。PGDialect類的行為,特定的PostgreSQL數(shù)據(jù)庫的使用,如ARRAY數(shù)據(jù)類型和架構(gòu)目錄; PGDialect_psycopg2 類,然后提供特定的psycopg2的DBAPI的行為,包括Unicode數(shù)據(jù)處理程序和服務(wù)器端游標(biāo)的行為。 圖20.3:簡單的方言/的ExecutionContext層次
上述模式的一個變體提出了自己在處理一個DBAPI支持多個數(shù)據(jù)庫。這方面的例子包括pyodbc,其中涉及任意數(shù)量的后端數(shù)據(jù)庫通過ODBC,和一個Jython與JDBC驅(qū)動程序,其中涉及zxjdbc,。以上關(guān)系是增加了一個mixin類,從在使用sqlalchemy.connectors包提供DBAPI的行為,是常見的多個后端。圖20.4說明了常見的功能sqlalchemy.connectors.pyodbc之間共享MySQL和Microsoft SQL Server的的pyodbc特定方言。 圖20.4:普通DBAPI方言層次之間共享的行為
Dialect ExecutionContext對象提供了一種手段定義與數(shù)據(jù)庫和DBAPI每一次互動,包括如何連接參數(shù)的格式和如何特殊在語句執(zhí)行期間被處理的怪癖。的Dialect 也是一個SQL編譯結(jié)構(gòu),使工廠SQL正確的目標(biāo)數(shù)據(jù)庫,和類型的對象定義Python的數(shù)據(jù)應(yīng)如何封從目標(biāo)DBAPI和數(shù)據(jù)庫。 20.4。架構(gòu)定義
建立與數(shù)據(jù)庫的連接和交互性,接下來的任務(wù)提供創(chuàng)建和操縱的后端無關(guān)SQL語句。要做到這一點,首先,我們需要確定我們將如何參照的表和列呈現(xiàn)在一個數(shù)據(jù)庫中的所謂的綱目表和列代表數(shù)據(jù)是有組織的,和大多數(shù)的SQL語句組成的表達式,參照這些結(jié)構(gòu)的命令。
一個的ORM或數(shù)據(jù)訪問層需要提供編程訪問SQL的語言,在該基地是一個編程的系統(tǒng)描述表。這是SQLAlchem??y的核心提供了第一個強大的部門ORM,提供的Table和Column的結(jié)構(gòu)描述數(shù)據(jù)庫的結(jié)構(gòu)獨立于用戶的模型類確定目標(biāo)背后的分工模式定義對象關(guān)系映射的關(guān)系架構(gòu)可以設(shè)計明確的關(guān)系型數(shù)據(jù)庫,包括特定于平臺的沒有被混亂的對象 - 關(guān)系的概念,這些細(xì)節(jié),如果有必要,仍然是一個單獨的關(guān)注。作為獨立的的ORM成分也架構(gòu)描述系統(tǒng)是一樣有用的任何其他類型的對象 - 關(guān)系系統(tǒng)可建立在核心。
Table和Column模型屬于的范圍是什么被稱為元數(shù)據(jù) ,提供一個集合對象的MetaData來表示Table對象的集合。這種結(jié)構(gòu)來源于Martin Fowler的描述大多來自“元數(shù)據(jù)映射”企業(yè)應(yīng)用架構(gòu)模式 。圖20.5所示一些關(guān)鍵要素的sqlalchemy.schema包。 圖20.5:基本sqlalchem??y.schema的對象
Table代表一個實際的表的名稱和其他屬性目前在目標(biāo)模式。它的Column對象的集合代表命名并鍵入有關(guān)單個表列的信息。一個完整的數(shù)組對象的描述約束,索引和序列設(shè)置,以填補在有更多的細(xì)節(jié),其中一些影響的引擎和SQL施工系統(tǒng)行為。特別是, ForeignKeyConstraint 是中央確定兩個表中應(yīng)加入。
架構(gòu)中的包Column Table和Column相對于其余的是唯一的包,因為它們是雙繼承,無論從sqlalchemy.schema包,sqlalchemy.sql.expression包,服務(wù)不只是為模式水平結(jié)構(gòu),但也可作為核心的SQL表達式語言的語法單位。圖20.6中示出這種關(guān)系。 圖20.6:表和列的雙重生活
在圖20.6中,我們可以看到, Table和Column繼承的SQL世界具體形式“的東西,你可以選擇”,被稱為一個FromClause ,和“東西,你可以使用SQL表達式”,被稱為一個ColumnElement 。 20.5SQL表達式
在SQLAlchem??y的創(chuàng)作中,SQL生成的方法是不明確的。文本語言可能是一個可能的候選人,這是一種常見的方法是在知名的核心對象 - 關(guān)系的工具像Hibernate的HQL。然而,對于Python,更有趣的選擇是:使用Python對象和表達式generatively建設(shè)的表達式目錄樹結(jié)構(gòu),甚至利用Python的運營商,所以運營商可以給定的SQL語句行為。
雖然它可能不會一直是這樣做的第一個工具,全歸功于在伊恩的SQLBuilder庫Bicking SQLObject來的靈感系統(tǒng)的使用Python對象和運營商SQLAlchem??y的表達語言。在這種方法中,Python對象代表一個SQL的詞匯部分表達。在這些對象上的方法,以及重載運算符,產(chǎn)生新的詞匯結(jié)構(gòu)來源于它們。最常見的目的是“列”將代表這些對象SQLObject的一個ORM映射類.q屬性可以通過使用一個命名空間;SQLAlchemy的命名屬性.c 。的.c 屬性今天仍然是核心的可選元素,如表和select語句。 表達式樹
一個SQLAlchem??y的SQL表達式結(jié)構(gòu),這種結(jié)構(gòu)是非常你,如果你想創(chuàng)建解析SQL語句,它是一個解析樹,除了開發(fā)人員創(chuàng)建的解析樹直接,而不是它從一個字符串導(dǎo)出。的核心類型的節(jié)點,在該解析樹被稱為的ClauseElement , 圖20.7示出的關(guān)系ClauseElement一些關(guān)鍵類。 圖20.7:基本表達層次
通過使用構(gòu)造函數(shù),方法和重載的Python操作功能,這樣的語句結(jié)構(gòu)為:
SELECT ID FROM用戶,其中name =?
可能建造在Python中,如:
從導(dǎo)入表中sqlalchem??y.sql,列中,選擇用戶表('用戶'('身份證'),列,列(“名稱”))到stmt =選擇(user.c.id])。(user.c.name =='編輯')
在select 圖20.8中示出的結(jié)構(gòu)的上述select構(gòu)造。注意:表示包含的文本值'ed'內(nèi)_BindParam構(gòu)造,從而導(dǎo)致它被呈現(xiàn)為綁定參數(shù)標(biāo)記的SQL字符串使用一個問號。 圖20.8:例表達式樹
從樹形圖中,人們可以看到,通過一個簡單的降穿越節(jié)點可以快速創(chuàng)建一個呈現(xiàn)的SQL語句,我們會看到更細(xì)節(jié)一節(jié)中的語句編譯。 Python的操作方法
在SQLAlchem??y,這樣的表達式:
列('A')== 2
生產(chǎn)既不True也不False ,而是一個SQL表達式興建。 關(guān)鍵是使用Python特殊的重載操作符操作員功能:例如,方法如eq?,?ne?,le?,?lt?,?add?,?mul?。面向列表達式節(jié)點提供重載通過使用Python的操作人員的行為一個mixin ColumnOperators 。使用操作符重載,一個表達column('a') == 2等價于:
從sqlalchem??y.sql.expression進口_BinaryExpression從進口柱sqlalchem??y.sql,bindparam,距離sqlalchem??y.operators進口EQ _BinaryExpression(左=('a')的列中,右= bindparam('A',值= 2,獨特的= TRUE),=操作符式)
eq結(jié)構(gòu)實際上是一個函數(shù)從Python的內(nèi)置的operator 。代表運營商作為一個對象(例如,operator.eq ),而不是一個字符串(即, = )允許字符串表示定義在語句的編譯時間,當(dāng)數(shù)據(jù)庫方言信息是已知的。 精選集
負(fù)責(zé)渲染成文本的SQL表達式樹的中央級SQL是Compiled類。這個類有兩個主要的子類, SQLCompilerDDLCompiler 。SQLCompiler處理SQL的渲染操作為SELECT,INSERT,UPDATE和DELETE語句,統(tǒng)稱為數(shù)據(jù)查詢語言(DQL)DML(數(shù)據(jù)操縱語言),而DDLCompiler處理各種CREATE和列為DROP語句,數(shù)據(jù)定義語言(DDL)。有一個額外的類層次結(jié)構(gòu),重點圍繞字符串表示形式的類型,開始在TypeCompiler 。個人方言然后提供自己的所有三個編譯器類型的子類定義特定的目標(biāo)數(shù)據(jù)庫的SQL語言方面。圖20.9提供了一個相對于這個類層次的概述PostgreSQL的話。 圖20.9:編譯器的層次結(jié)構(gòu),包括PostgreSQL的具體實施
Compiled的子類定義了一系列的訪問方法,每個一提到一個特定的子類的ClauseElement 。層次結(jié)構(gòu)ClauseElement節(jié)點的一份聲明中行走,是通過每次訪問函數(shù)的遞歸連接的字符串輸出。由于這個收益, Compiled對象維護國家有關(guān)匿名標(biāo)識符名稱,綁定參數(shù)名稱,嵌套子查詢,除其他事項外,所有的生產(chǎn)的SQL語句的字符串,以及作為最終目的收集綁定的參數(shù)使用默認(rèn)值。圖20.10說明訪問方法的過程中,在文本單元。 圖20.10:呼叫層次的語句編譯
一個完成的Compiled結(jié)構(gòu)包含完整的SQL字符串,并綁定值的集合。這些都是強制的ExecutionContext到DBAPI的execute預(yù)期的格式 方法,其中包括這樣的考慮,治療的Unicode語句對象的集合類型使用存儲綁定值,以及具體如何綁定值自己應(yīng)該被強迫交涉適當(dāng)?shù)腄BAPI目標(biāo)數(shù)據(jù)庫。 20.6類映射的ORM
現(xiàn)在我們的注意力轉(zhuǎn)移到ORM。第一個目標(biāo)是使用系統(tǒng)表的元數(shù)據(jù)中,我們定義了允許一個用戶定義的類映射到數(shù)據(jù)庫表中的列的集合。第二個目標(biāo)是讓用戶定義的類之間的關(guān)系的定義,根據(jù)數(shù)據(jù)庫中的表之間的關(guān)系。
SQLAlchem??y的“映射”,是指這眾所周知的數(shù)據(jù)映射器模式描述在福勒的企業(yè)架構(gòu)模式 ??傮w而言,SQLAlchem??y的ORM大量借鑒由福勒的做法詳細(xì)介紹。它也嚴(yán)重影響了著名的Java關(guān)系映射工具Hibernate和伊恩Bicking為Python的SQLObject的產(chǎn)品。 古典與聲明
我們使用的術(shù)語古典映射到參考SQLAlchemy的系統(tǒng)的應(yīng)用對象 - 關(guān)系數(shù)據(jù)映射到一個現(xiàn)有的用戶類。這形式參考Table對象和用戶定義的類有兩個單獨定義的實體連接在一起,通過一個函數(shù)調(diào)用對映表,一旦mapper已應(yīng)用到一個用戶定義的類,類需要新的屬性對應(yīng)表中的列:
類用戶(對象):通過 映射(用戶user_table) ?,F(xiàn)在用戶有一個“id”屬性用戶名
mapper也可以貼上其他各種屬性的類,包括屬性對應(yīng)于其他種對象的引用,以及為任意的SQL表達式。粘貼任意屬性的過程中一類是被稱為在Python世界為“的monkeypatching”的,但由于我們是在數(shù)據(jù)驅(qū)動的和非任意的方式,這樣做的精神,操作的更好地表達這個術(shù)語類儀器儀表 。
現(xiàn)代使用的SQLAlchem??y的中心,周圍的聲明的擴展,這是一種可配置的系統(tǒng),類似于共同有效記錄系統(tǒng)所使用的許多其他類的聲明對象 - 關(guān)系的工具。在這個系統(tǒng)中,最終用戶明確定義屬性內(nèi)聯(lián)類的定義,每個代表一個屬性類,它是要被映射的。Table對象,在大多數(shù)情況下,是不明確提到,也不是mapper功能,只有類,Column對象,與其他ORM相關(guān)的屬性被命名為:
類用戶(基本):tablename?='用戶'ID =列(如Integer,primary_key的= TRUE)
它可能會出現(xiàn),上面的類儀器直接實現(xiàn)由我們的放置id = Column()但這種情況并非如此。的聲明擴展使用Python元類,這是一個方便的方法來執(zhí)行一系列的操作,每次一個新的類首先聲明,生成一個新的Table 從什么被宣布的對象,并通過它的mapper功能,隨著類。mapper功能,然后在完全相同的方式,它的工作修補它自己的屬性類上,在這種情況下向id屬性,和更換有以前。元類初始化的時候是完整的(也就是,當(dāng)執(zhí)行的流程離開由User劃定的塊),標(biāo)記的id Table User.id Column對象被移動到一個新的Table , User.id 已被替換特定映射由一個新的屬性。
它總是SQLAlchem??y的將有一個的簡寫,聲明的形式配置。然而,創(chuàng)造的聲??明延遲贊成繼續(xù)工作,鞏固了力學(xué)的經(jīng)典測繪的。中期的擴展名為ActiveMapper,這后來成為藥劑項目,早在存在。它重新定義映射構(gòu)造在一個更高的級別申報制度。聲明的目標(biāo)是扭轉(zhuǎn)藥劑的大量抽象的方向通過建立一個系統(tǒng)的方法保留SQLAlchem??y的經(jīng)典地圖繪制概念,幾乎確切地說,只有重組它們是如何使用不再繁瑣,更適合類級別的擴展比經(jīng)典的映射。
無論是古典或聲明的映射,映射的類需要新的行為,允許它來表達其屬性中的SQL結(jié)構(gòu)。SQLAlchem??y的最初跟著SQLObject的使用一個特殊的行為通過SQLAlchem??y的屬性為SQL列表達式的來源,提到.c ,在這個例子中:
結(jié)果= session.query(用戶)。過濾器(User.c.username =='編輯')。所有的()
然而,在0.4版本中,SQLAlchem??y的移動到映射的功能屬性本身:
結(jié)果= session.query(用戶)。過濾器(User.username =='編輯')。所有的()
在屬性的訪問證明了這種變化有很大的改進,因為它寵物的列狀的物體目前的類,以獲得額外的類特定的功能目前來自直接從底層Table對象。很顯然,那位同事是位多產(chǎn)教案,列表名單很大,所以教師選擇更先進的搜索,并增加了也允許使用不同的類屬性之間的整合,如直接指到表列的屬性,屬性,來自這些列的SQL表達式和屬性,請參閱相關(guān)的類。最后,它提供了一個對稱之間的映射類,同樣的屬性,以及該映射的類的實例,可以采取不同的行為取決于類型的父。綁定類屬性返回SQL表達式,同時結(jié)合實例屬性返回實際的數(shù)據(jù)。 映射的剖析
一直連接到我們的id User類的id屬性,是一種在Python中的對象,對象為一個描述符有get?,?set,和del方法,它的Python運行時按照所有涉及該屬性的類和實例操作。SQLAlchemy的實施稱為一個InstrumentedAttribute ,我們將舉例說明背后所呈現(xiàn)的世界與另一個例子。從一個Table和一個用戶定義的類,我們建立了一個映射只有一個映射列relationship ,以及相關(guān)的類,它定義了一個參考:
user_table表(“用戶”,元數(shù)據(jù),列('身份證',整數(shù),primary_key的= TRUE),) 類用戶(對象):通過 映射器(用戶,user_table,屬性= {“相關(guān)”的關(guān)系(地址)})
當(dāng)映射的結(jié)構(gòu)是完整的,有關(guān)的類的對象的詳細(xì)的圖20.11中。 圖20.11:映射的剖析
該圖說明了SQLAlchem??y的映射定義為兩個獨立的層用戶定義的類和表的元數(shù)據(jù)之間的互動,它被映射。圖向左類儀器儀表,而SQL和數(shù)據(jù)庫功能是朝著正確的合照。一般模式玩的是對象的組合是用來隔離行為的角色和對象繼承用來區(qū)分在一個特定的角色之間的行為差??異。
類儀器儀表領(lǐng)域內(nèi), ClassManager被映射的類,而其收集的InstrumentedAttribute對象是與每個屬性映射的類。InstrumentedAttribute是面向公眾的Python的描述符前面提到的,產(chǎn)生SQL表達式時,使用基于類的表達式(例如, User.id==5 )。.在...時候, 何時處理的一個實例User , InstrumentedAttribute代表的行為歸因于AttributeImpl對象,這是一個專門對幾個品種所表示的數(shù)據(jù)類型。
建立的映射側(cè), Mapper代表一個用戶定義的類和一個可選擇的單元的聯(lián)動,最典型的Table 。Mapper維護一組每個屬性的對象,被稱為為MapperProperty ,其中涉及的SQL表示的特定屬性。最常見的變種MapperProperty ColumnProperty ,一個映射的字段或SQL表達式,并RelationshipProperty ,代表一個連接到另一個映射。
MapperProperty代表屬性裝載行為,包括屬性如何呈現(xiàn)在一個SQL語句,以及如何從結(jié)果來填充行一個LoaderStrategy對象,其中有幾個品種。不同LoaderStrategies確定的裝載行為,屬性被延遲 , 躍躍欲試 ,或直接 。選擇默認(rèn)的版本映射配置時間,在查詢時可以選擇使用一個備用的策略。RelationshipProperty也的引用了DependencyProcessor ,處理,如何映射器間的依賴關(guān)系和屬性同步進行沖洗時間。父和目標(biāo)的關(guān)系幾何形狀的基礎(chǔ)上選擇DependencyProcessor selectables鏈接關(guān)系。
的的Mapper / RelationshipProperty結(jié)構(gòu)形成一個圖,其中Mapper對象的節(jié)點RelationshipProperty對象的有向邊。一旦全套映射器已被宣布由一個應(yīng)用程序,遞延“初始化”步驟被稱為組態(tài)前進。它主要用于每個RelationshipProperty ,以鞏固其母公司和細(xì)節(jié)之處的目標(biāo)映射器,包括選擇的AttributeImpl以及作為DependencyProcessor 。此圖是一個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),用于整個操作過程中的ORM。它參與操作,如所謂的“級聯(lián)”的行為,定義了如何操作應(yīng)該傳播沿著對象的路徑,查詢操作相關(guān)的對象和集合“眼巴巴”加載一次,以及對對象沖洗側(cè)一個之前建立的所有對象引發(fā)了一系列的依賴圖持久性的步驟。 20 / 7查詢和裝載行為
SQLAlchemy的啟動通過一個對象調(diào)用Query所有對象的裝載行為?;A(chǔ)狀態(tài)Query開始,包括實體 ,這是映射類列表和/或獨立的SQL表達式進行查詢。它也有一個參考Session ,它表示連接到一個或多個數(shù)據(jù)庫,以及一個高速緩存的數(shù)據(jù)的相對于累計這些連接上的交易。下面是一個基本的用法示例:
從sqlalchem??y.orm導(dǎo)入Session屆會議(發(fā)動機)查詢session.query(用戶)
我們創(chuàng)建了一個Query ,將產(chǎn)生的User情況下,相對于一個新的Session ,我們已經(jīng)創(chuàng)建。在同一Query提供了一個生成生成器模式select結(jié)構(gòu)的方式前面所討論的,額外的標(biāo)準(zhǔn)和修飾符與在一份聲明中構(gòu)造一個方法調(diào)用的時間。當(dāng)一個迭代運算被稱為上的Query ,它構(gòu)造一個SQL表達式構(gòu)造代表一個SELECT,把它發(fā)射到數(shù)據(jù)庫中,然后解釋的結(jié)果集行面向ORM的結(jié)果對應(yīng)于所請求的實體的初始集合。
Query進行硬的SQL渲染的區(qū)別 和數(shù)據(jù)加載的操作的部分。前者是指建設(shè)一個SELECT語句,后者的解釋SQL結(jié)果行ORM映射的構(gòu)造。數(shù)據(jù)加載,其實,繼續(xù)進行沒有一個SQL呈現(xiàn)步驟,的Query可能會被要求解釋結(jié)果一個文本查詢手由用戶組成。
這兩個SQL渲染和數(shù)據(jù)加載利用遞歸下降形成的曲線圖由一系列鉛Mapper對象,考慮每一列或SQL表達式控股ColumnProperty作為一個葉子結(jié)點,每個這是通過所謂的“急切負(fù)荷”要包含在查詢中的RelationshipProperty作為一個邊緣到另一個Mapper節(jié)點。遍歷和要采取的行動,在每個節(jié)點最終是每個LoaderStrategy與每MapperProperty相關(guān)工作,添加列,并加入到正在興建的SELECT語句在SQL呈現(xiàn)階段,Python函數(shù)來處理結(jié)果行中的數(shù)據(jù)加載階段。
Python函數(shù)中的數(shù)據(jù)加載階段,每個接收數(shù)據(jù)庫中的一行,因為它們是牽強,產(chǎn)生的狀態(tài)可能有變在存儲器中的映射的屬性作為一個結(jié)果。它們產(chǎn)生的一個特定的屬性有條件的,根據(jù)檢查結(jié)果集的第一個入行,以及加載選項。如果負(fù)載的屬性是不繼續(xù)進行,沒有可調(diào)用的函數(shù)。
圖20.12說明了遍歷幾個LoaderStrategy對象中加入的渴望加載 情況下,說明其提供的SQL語句的連接過程中發(fā)生的_compile_context 方法Query 。這也表明新一代的的行人口的功能,收到的結(jié)果行和填充單個對象的屬性,這個過程發(fā)生在instances的Query方法。 圖20.12:穿越的裝載機的戰(zhàn)略,包括一個加入預(yù)先加載
SQLAlchem??y的早期結(jié)果來填充方法使用傳統(tǒng)的穿越固定對象的方法與每一個收到的每一行的戰(zhàn)略和采取相應(yīng)的行動。加載程序可調(diào)用的系統(tǒng),首先在0.5版本中引入的,代表一個巨大的飛躍,性能,因為很多決策就行可以了只是一次處理了前面,而不是為每一行,和一個顯著數(shù)量的函數(shù)調(diào)用沒有凈影響可能會被淘汰。 20.8會議/標(biāo)識映射
在SQLAlchem??y,Session對象的實際使用情況,提出了公共接口ORM的,也就是說,加載和持久化數(shù)據(jù)。它提供的起始角度為給定的數(shù)據(jù)庫連接查詢和堅持行動。
Session ,除了作為數(shù)據(jù)庫連接的網(wǎng)關(guān),這是目前所有映射實體的集合保持一個積極的參考在內(nèi)存中相對于該Session 。在這樣的Session 的身份地圖和單位的工作模式,既實現(xiàn)了一個門面確定由福勒。一個數(shù)據(jù)庫唯一的身份標(biāo)識映射保持映射為一個特定的Session中的所有對象,消除了存在的問題重復(fù)的身份介紹。工作單位的基礎(chǔ)上的身份地圖提供的持久化狀態(tài)的變化過程自動化系統(tǒng)數(shù)據(jù)庫中的盡可能最有效的方式。實際的持久性步驟是被稱為“沖洗”,和在現(xiàn)代的SQLAlchem??y此步驟通常是自動的。 發(fā)展歷史
Session開始大多隱蔽系統(tǒng)負(fù)責(zé)單散發(fā)出齊平的任務(wù)。沖洗過程中涉及發(fā)光SQL報表到數(shù)據(jù)庫中,對應(yīng)的對象的狀態(tài)中的變化跟蹤工作制的單位,從而同步的當(dāng)前狀態(tài)在內(nèi)存中的數(shù)據(jù)庫。的沖洗一直是一個最SQLAlchem??y的復(fù)雜的操作。
方法的調(diào)用非常早期版本的同花順開始在背后被稱為commit ,這是方法上存在一個隱式的,線程局部對象objectstore 。當(dāng)一個人使用SQLAlchem??y的0.1,因此沒有必要打電話Session.add ,也沒有任何一個明確的概念Session的。唯一的面向用戶的步驟是創(chuàng)建映射器,創(chuàng)建新的對象,修改現(xiàn)有對象加載查詢(查詢每個Mapper對象直接從自己被調(diào)用),然后堅持所有通過objectstore.commit命令。池中的對象的一組操作無條件模塊全局的和無條件的線程局部。
與第一組objectstore.commit模型是直接命中的用戶,但此模型的剛性很快撞上了墻?,F(xiàn)代SQLAlchem??y的新用戶有時感嘆,需要定義一個工廠,可能是注冊表,Session對象,以及需要保持自己的對象組織成只是一個Session的時間,但是這是遠(yuǎn)遠(yuǎn)最好的初期,當(dāng)整個系統(tǒng)完全是隱含的?!?.1使用模式的方便,在很大程度上仍是在現(xiàn)代社會本SQLAlchem??y的,其特點通常配置為一個會話注冊表使用線程局部范圍。
Session本身只介紹SQLAlchemy的0.2版,建模后在Hibernate Session對象存在松散。這個版本的特色綜合事務(wù)控制,其中的Session可以被放置到一個事務(wù)中通過begin方法,并完成通過commit方法。objectstore.commit方法更名為objectstore.flush ,新的Session對象可以在任何時間創(chuàng)建。Session本身被打破了從另一個對象UnitOfWork ,這仍然是一個私人反對負(fù)責(zé)執(zhí)行實際的刷新操作。
,雖然沖洗過程中顯式調(diào)用方法用戶,0.4系列的SQLAlchemy的概念引入的自動刷新 ,這意味著,刷新每次查詢前立即發(fā)出。它的優(yōu)點自動刷新的是,所發(fā)出的SQL語句的查詢總是有關(guān)系側(cè)訪問的確切狀態(tài),存在于存儲器中,所有的改變都送了過來。早期版本的SQLAlchem??y的不包括此功能,因為最常見的使用模式FLUSH語句也承諾永久性的變化。但是,當(dāng)自動刷新?lián)榻B,它是伴隨著另一個特點所謂的事務(wù)性 Session ,它提供了一個Session會自動啟動的交易中,一直持續(xù)到用戶名為commit明確。此功能的推出, flush方法不再犯,它刷新的數(shù)據(jù),并能安全被稱為一個自動化的基礎(chǔ)上。Session ,而現(xiàn)在,提供了一步一步的同步內(nèi)存中的狀態(tài)和SQL查詢狀態(tài)之間進行沖洗根據(jù)需要,什么也沒有永久持續(xù),直到明確commit第一步。這種行為是,事實上,在Hibernate中完全相同的Java。然而,SQLAlchem??y的擁抱為Python相同的行為在風(fēng)暴ORM的基礎(chǔ)上,使用這種風(fēng)格的介紹SQLAlchem??y的是在0.3版本的時候。
0.5版帶來了更多的交易整合后交易到期推出后,每一個commit或rollback ,默認(rèn)所有國家內(nèi)的Session已過期(清除),來填充后續(xù)SQL語句時再重新選擇數(shù)據(jù)時,或當(dāng)在剩余的過期的對象的屬性中訪問新事務(wù)的上下文中。最初,SQLAlchem??y的周圍建造假設(shè)SELECT語句應(yīng)盡可能少排放,無條件的。過期的提交行為是緩慢的,在此原因,但是,它完全解決問題的Session載有過時的數(shù)據(jù)交易后,沒有簡單的方式來加載新的數(shù)據(jù)沒有重建的全套已加載的對象。在早期,它似乎這個問題不能合理解決,因為它是看不出來的時Session應(yīng)考慮目前的狀態(tài)是過時的,從而昂貴的新集的SELECT語句在下次訪問。但是,一旦Session轉(zhuǎn)移到一個始終保持在一個交易模型,交易結(jié)束點變得明顯,自然點的數(shù)據(jù)過期,作為一個事務(wù)的性質(zhì)具有高度隔離是, 它不能看到新的數(shù)據(jù),直到它的承諾或回滾了。不同的數(shù)據(jù)庫和配置,當(dāng)然有不同程度的事務(wù)隔離,包括沒有在所有的交易。這些模式的使用是完全可以接受的,SQLAlchem??y的到期使用較低的隔離模型,開發(fā)人員只需要知道,水平內(nèi)如果有多個會話的會話可能會使未隔離的變化共享相同的行。這是不是在所有不同,什么都可以發(fā)生時直接使用兩個數(shù)據(jù)庫連接。 會議概述 圖20.13說明了Session的主要結(jié)構(gòu)處理。 圖20.13:會議概述
面向公眾的部分上面是Session本身和用戶對象的集合,每一個映射的類的一個實例。在這里,我們看到映射的對象保持一個SQLAlchemy的建設(shè)的參考InstanceState ,跟蹤ORM一個單獨的實例包括待處理的屬性的變化和屬性的狀態(tài)過期狀態(tài)。InstanceState 在前面的討論是實例級側(cè)的屬性儀表節(jié), 映射的剖析 ,一流水平的ClassManager相對應(yīng),并保持狀態(tài)的映射對象的字典(即Python的dict?代表的AttributeImpl相關(guān)聯(lián)的對象的類屬性) 。 狀態(tài)跟蹤
IdentityMap是數(shù)據(jù)庫身份InstanceState對象的映射,對于那些有一個數(shù)據(jù)庫的身份,這被稱為持久性的對象。的默認(rèn)實現(xiàn)IdentityMap與InstanceState自我管理其大小所有強引用刪除用戶映射的情況下,一旦他們已被刪除的它的工作方式以同樣的方式作為Python的WeakValueDictionary 。、 保護組的所有對象標(biāo)記為臟或刪除 ,以及有待對象的標(biāo)新 ,收集垃圾,通過建立強大的對這些對象的引用掛起的更改。所有的強引用,然后被丟棄后沖水。
InstanceState也執(zhí)行的關(guān)鍵任務(wù),保持“有什么變化”對于一個特定的對象的屬性,使用此舉變化系統(tǒng)“先前”的一個特定的屬性值存儲在字典中稱為committed_state前傳入的值賦給對象的電流詞典。沖洗時間,內(nèi)容committed_state 和與該對象相關(guān)聯(lián)的dict比較,以產(chǎn)生組凈變化對每個對象。
在集合的情況下,一個單獨的collections包坐標(biāo)與InstrumentedAttribute / InstanceState 系統(tǒng),以保持一個特定的映射集合的集合變動凈額del常見的Python類,如set , list和dict的子類在使用前和增強與歷史跟蹤mutator方法。收集系統(tǒng)在0.4?是開放式的,可用于任何集合類對象進行了修改。 事務(wù)控制
Session ,在默認(rèn)狀態(tài)下的使用,維護打開事務(wù)的所有操作完成時commit或rollback被稱為?!癝essionTransaction維護一組零個或多個Connection對象,每個對象代表一個開放的交易在一個特定的數(shù)據(jù)庫。SessionTransaction是一個懶惰的初始化的對象,開始沒有數(shù)據(jù)庫的狀態(tài)存在。作為一個特殊的后端需要參加在一份聲明中執(zhí)行, Connection對應(yīng)于該數(shù)據(jù)庫添加到SessionTransaction的名單連接安全要求.雖然在一個時間是一個單一的連接常見的,支持多種連接方案在特定的連接,用于一個特定的操作基于配置與Table , Mapper或SQL構(gòu)建自己參與運作。多重連接也可以使用協(xié)調(diào)事務(wù)兩相的的行為,它提供那些DBAPIs。 20.9工作單位
提供flush Session將在其工作的flush方法一個獨立的模塊unitofwork 。正如前面提到的,沖洗過程可能是SQLAlchem??y的最復(fù)雜的功能。
工作單位的工作是將所有的掛起狀態(tài),目前在一個特定的Session到數(shù)據(jù)庫中,掏空了new , dirty ,和deleted 收藏保持的Session 。完成后,內(nèi)存中的狀態(tài)Session的,什么是在當(dāng)前事務(wù)中的比賽。面臨的主要挑戰(zhàn)是確定正確的一系列的持久性的步驟,然后按正確的順序來執(zhí)行它們。這包括確定INSERT,UPDATE和DELETE語句的列表,其中包括因從級聯(lián)的相關(guān)行被刪除或以其他方式移動,確保UPDATE報表只包含那些真正被修改的列,建立“同步”操作外鍵引用的主鍵列,將復(fù)制的狀態(tài)列,在該點在該新生成的主密鑰標(biāo)識符可確保發(fā)生插入的對象添加到Session的順序盡可能有效,并確保UPDATE和DELETE語句出現(xiàn)在一個確定順序所以,以減少機會死鎖。 歷史
作為一個糾纏不清的系統(tǒng)結(jié)構(gòu),工作落實的單位開始寫在一個特設(shè)的方式,它的發(fā)展可以進行比較,發(fā)現(xiàn)沒有出路的森林地圖。早期的錯誤和缺少行為解決與螺栓連接修復(fù),而一些重構(gòu),改善的事項通過0.5版本,它直到0.6版本,工作單位,時間穩(wěn)定,很好理解,所涵蓋的上百個測試完全從頭開始重寫。經(jīng)過幾個星期的考慮一個新的的方法,將驅(qū)動由一致的數(shù)據(jù)結(jié)構(gòu),過程重寫它使用這個新的模型只用了幾天,當(dāng)時的想法是這個時候,充分的了解。它也是的事實,極大地促進了新實施??的行為可能是仔細(xì)對現(xiàn)有版本進行交叉檢查。此過程顯示如何在第一次迭代的東西,但是可怕的,仍然是有價值的,因為只要它提供了一個工作模型。這進一步顯示了總的一個子系統(tǒng)重寫往往是不僅是適當(dāng)?shù)模粋€不可分割的一部分的發(fā)展難以開發(fā)的系統(tǒng)。 拓?fù)渑判?/p>
后面的工作單元的主要范式是組裝的完整列表,要采取的行動到一個數(shù)據(jù)結(jié)構(gòu)中,每個節(jié)點代表一個單一的步驟;在設(shè)計模式中的說法,這被稱為命令模式 。的一系列在該結(jié)構(gòu)中的“命令”,然后組織成一個特定的順序使用拓?fù)渑判?。拓?fù)渑判蚴且粋€過程,一個偏序 ,各種項目的基礎(chǔ)上,也就是說,只有某些元素必須先于其他人。圖20.14說明了拓?fù)渑判虻男袨椤?圖20.14:拓?fù)渑判?/p>
工作單位構(gòu)建了一個偏序,那些持久的命令,必須先別人的基礎(chǔ)上?!懊睿缓笸?fù)渑判?,以便調(diào)用。確定哪些命令之前,主要來自存在的relationship ,填補了兩個Mapper對象一般, Mapper 被認(rèn)為是依賴于其他,作為relationship意味著一個Mapper 有一個外鍵依賴于其他。類似的規(guī)則存在許多to-many關(guān)聯(lián)表,但在這里,我們專注于的情況下,one-to-many/many-to-one關(guān)系。外鍵的依賴性問題解決為了防止發(fā)生,沒有依賴于無需違反約束標(biāo)記作為“遞延”的約束。但同樣重要的是,排序允許主鍵標(biāo)識符,這在許多平臺上時,只產(chǎn)生一個INSERT其實時,被公正執(zhí)行INSERT語句的結(jié)果填充到參數(shù)依賴的行是關(guān)于要插入列表。刪除,使用相同的順序在反向相關(guān)的行之前被刪除那些他們賴以生存,這些行所指的外鍵是不存在的,沒有演示文稿
工作單位提供系統(tǒng)拓?fù)渑判蛟趦蓚€不同的級別,進行依賴關(guān)系的結(jié)構(gòu)的基礎(chǔ)上演示文稿第一個層次,持久性的步驟組織成桶的基礎(chǔ)上之間的依賴關(guān)系的映射器,即,完整的“桶”的對象對應(yīng)某個特定的類。第二電平打破了零個或多個這些“桶”成較小的批次,處理的情況下,參考周期或自參照表。如圖20.15所示的“桶”產(chǎn)生的插入的一組User的對象,那么一組Address的對象,其中一個中間步驟,復(fù)制新生成的主鍵的值到User每個Address對象的user_id外鍵列。 圖20.15:組織對象的映射
在每個映射分揀情況,任何數(shù)目的User和Address對象可以被刷新沒有任何影響的復(fù)雜的步驟或多少“依賴關(guān)系”必須考慮的。
排序第二個層次的組織之間的直接依賴關(guān)系的基礎(chǔ)上的持久性步驟在一個單一的映射器的范圍之內(nèi)的單個對象。當(dāng)發(fā)生這種情況時,最簡單的例子是一個表,其中包含一個外鍵約束本身??需要一個特定的表中的行前插入另一行同一表中的,是指它的。另一是一系列的表格時有一個參考周期 :A引用了表B表,它引用表C,然后參考表A.在別人面前,一些A的對象必須插入允許的B和C的對象,也可以插入。表,該表是指本身是一種特殊的情況下,參考周期。
要確定哪些業(yè)務(wù)可以保持在其合并的,每個Mapper桶,將被分解成一個更大的集合的每個對象的命令,一個周期檢測算法被施加到映射器之間存在的依賴關(guān)系的設(shè)定,使用一個修改的版本的一個周期Guido van Rossum的博客上發(fā)現(xiàn)的檢測算法。這些桶在周期是然后再破碎成每個對象的操作和通過混入的集合的每個映射器水桶此外,每個對象桶的新的依賴規(guī)則每映射桶。如圖20.16所示桶中的User對象被分解成單個每個對象的命令,此外,從relationship User到一個新的contact relationship本身稱為contact造成的。 圖20.16:組織各個步驟的參考周期
鏟斗結(jié)構(gòu)背后的基本原理是,它允許共同的批處理報表盡可能地,既減少所需的步數(shù)Python和實現(xiàn)更有效的互動與DBAPI,有時可以執(zhí)行一個Python的報表內(nèi)方法調(diào)用。只有當(dāng)一個參考周期之間存在著映射器每個對象的依賴模式更昂貴的踢,即使如此,它只發(fā)生對象圖需要它的那些部分。 {0}·{/0}{1} {/1}{2}20 10{/2}總結(jié)
SQLAlchem??y的目的是非常高的的目標(biāo)是自成立以來,最豐富的功能和靈活的數(shù)據(jù)庫產(chǎn)品。它已完成因此,雖然維持其專注于關(guān)系型數(shù)據(jù)庫,認(rèn)識到在深入和全面的方式支持關(guān)系型數(shù)據(jù)庫的用處是一大創(chuàng)舉,即使是現(xiàn)在,范圍的承諾繼續(xù)顯露自己比以前認(rèn)為的大。
的基于組件的方法的目的是提取每個區(qū)域的最可能值從的功能,提供了許多不同的單位,應(yīng)用程序可以單獨使用或組合使用。該系統(tǒng)已具有挑戰(zhàn)性的創(chuàng)建,維護,和交付。
發(fā)展課程的目的是緩慢的基礎(chǔ)上,理論,堅實的功能是有條不紊的,基礎(chǔ)廣泛的建設(shè),最終更有價值比快速傳遞功能,而無需基礎(chǔ)。它采取了很長一段時間的SQLAlchem??y興建。 一個一致的,記錄用戶的故事,但在整個過程中,底層構(gòu)架始終領(lǐng)先一步,在某些情況下,“時間機器”的效果功能,可幾乎在添加用戶要求他們。
Python語言一直是一個可靠的主機(如果有點挑剔的,特別是在該地區(qū)的性能)。語言的SQLAlchem??y的一致性,極大地開放運行模式允許提供一個更好的比其他語言編寫的同類產(chǎn)品所提供的經(jīng)驗。
這是希望的SQLAlchem??y的項目,Python的收益不斷更深的接納到盡可能廣泛的各種各樣的盡可能的領(lǐng)域和行業(yè),使用關(guān)系型數(shù)據(jù)庫仍然充滿活力和進步的。這么做的目標(biāo)是?SQLAlchem??y是表明,關(guān)系型數(shù)據(jù)庫,Python中,考慮的對象模型都是非常有價值的開發(fā)工具。
更多建議: