SQLAlchemy學(xué)習(xí)筆記(一)

SQLAlchemy學(xué)習(xí)筆記(一)

為什么要使用SQLAlchemy?

將你的代碼抽象出來(lái)不依賴與數(shù)據(jù)庫(kù)的類型和某種數(shù)據(jù)庫(kù)自身的的獨(dú)特性绽左,SQLAlchemy提供了強(qiáng)大又通用的語(yǔ)句和類型,你不在需要考慮你所選用數(shù)據(jù)庫(kù)的實(shí)現(xiàn)及其廠商面氓。SQLAlchemy同樣使得將數(shù)據(jù)邏輯從Oracle或者PostgreSQL到你的應(yīng)用程序的數(shù)據(jù)庫(kù)或者其他數(shù)據(jù)倉(cāng)庫(kù)。它將將對(duì)數(shù)據(jù)庫(kù)的操作在提交給數(shù)據(jù)庫(kù)之前進(jìn)行了統(tǒng)一的規(guī)范和轉(zhuǎn)義蒸播。這樣就避免了一些常見(jiàn)的問(wèn)題例如數(shù)據(jù)庫(kù)注入攻擊歇由。

SQLAlchemy通過(guò)兩種主要的數(shù)據(jù)庫(kù)訪問(wèn)方式提供了強(qiáng)大的靈活性:SQL表達(dá)式和ORM。這些方式可以單獨(dú)使用也可以結(jié)合使用瓮栗,完全取決于你的喜好和應(yīng)用程序的需要削罩。

SQLAlchemy Core和 SQL Expression Language

SQL表達(dá)式是一種比較Pythonic的方式取代原始的SQL語(yǔ)句瞄勾,它是一個(gè)對(duì)原始SQL語(yǔ)言的初級(jí)抽象锦募,雖然聚焦于具體的數(shù)據(jù)庫(kù)废亭,然而,通過(guò)對(duì)多數(shù)的后端數(shù)據(jù)庫(kù)提供了統(tǒng)一的語(yǔ)言實(shí)現(xiàn)了訪問(wèn)方式的統(tǒng)一萝衩。

ORM

SQLAlchemy ORM類似于你在其他語(yǔ)言中可能遇到的許多其他對(duì)象關(guān)系映射器(ORM)微服。它關(guān)注于應(yīng)用程序的領(lǐng)域模型趾疚,并利用工作模式單元來(lái)維護(hù)對(duì)象狀態(tài)。它還在SQL表達(dá)式語(yǔ)言之上提供了高級(jí)抽象以蕴,使用戶能夠以更習(xí)慣的方式工作糙麦。您可以混合使用ORM和SQL表達(dá)式語(yǔ)言來(lái)創(chuàng)建非常強(qiáng)大的應(yīng)用程序。ORM利用了一個(gè)聲明式系統(tǒng)丛肮,該系統(tǒng)與許多其他ORM(如Ruby on Rails中的ORM)使用的活動(dòng)記錄系統(tǒng)類似赡磅。

雖然ORM非常有用,但您必須記住腾供,在關(guān)聯(lián)類的方式和底層數(shù)據(jù)庫(kù)關(guān)系的工作方式之間是有區(qū)別的仆邓。在第6章中,我們將更全面地探討這種方法如何影響您的實(shí)現(xiàn)伴鳖。

在SQLAlchemy Core和ORM之間如何選擇节值?

在開(kāi)始使用SQLAlchemy構(gòu)建應(yīng)用程序之前,您需要決定是主要使用ORM還是Core榜聂。選擇SQLAlchemy Core或ORM作為應(yīng)用程序的主要數(shù)據(jù)訪問(wèn)層通常取決于幾個(gè)因素和個(gè)人偏好搞疗。

這兩種模式使用的語(yǔ)法略有不同,但是Core和ORM之間最大的區(qū)別是將數(shù)據(jù)視為模式或業(yè)務(wù)對(duì)象须肆。SQLAlchemy Core有一個(gè)以模式為中心的視圖匿乃,它與傳統(tǒng)SQL一樣,主要關(guān)注表豌汇、鍵和索引結(jié)構(gòu)幢炸。SQLAlchemy Core在數(shù)據(jù)倉(cāng)庫(kù)、報(bào)告拒贱、分析和其他場(chǎng)景中非常出色宛徊,在這些場(chǎng)景中,能夠嚴(yán)格控制查詢或?qū)ξ唇5臄?shù)據(jù)進(jìn)行操作非常有用逻澳。強(qiáng)大的數(shù)據(jù)庫(kù)連接池和結(jié)果集優(yōu)化非常適合處理大量數(shù)據(jù)闸天,甚至在多個(gè)數(shù)據(jù)庫(kù)中也是如此。

但是斜做,如果您希望更多地關(guān)注領(lǐng)域驅(qū)動(dòng)的設(shè)計(jì)苞氮,ORM將在元數(shù)據(jù)和業(yè)務(wù)對(duì)象中封裝大部分底層模式和結(jié)構(gòu)。這種封裝可以使數(shù)據(jù)庫(kù)交互更像普通的Python代碼瓤逼。大多數(shù)常見(jiàn)的應(yīng)用程序都適合以這種方式建模笼吟。它也可以是引入領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)的一種非常有效的方法库物,將SQLAlchemy引入到遺留應(yīng)用程序中,或者在整個(gè)應(yīng)用程序中散布原始SQL語(yǔ)句贷帮。微服務(wù)還受益于底層數(shù)據(jù)庫(kù)的抽象艳狐,允許開(kāi)發(fā)人員只關(guān)注正在實(shí)現(xiàn)的流程。

但是皿桑,由于ORM是在SQLAlchemy Core之上構(gòu)建的毫目,所以您可以使用它處理Oracle數(shù)據(jù)倉(cāng)庫(kù)和Amazon Redshift等服務(wù)的能力,就像它與MySQL交互一樣诲侮。當(dāng)您需要組合業(yè)務(wù)對(duì)象和存儲(chǔ)的數(shù)據(jù)時(shí)镀虐,這對(duì)于ORM來(lái)說(shuō)是一個(gè)極好的補(bǔ)充。

這里有一個(gè)快速清單沟绪,可以幫助你決定哪種選擇最適合你:

  • 如果您使用的框架已經(jīng)內(nèi)建了ORM刮便,但希望添加更強(qiáng)大的報(bào)表,請(qǐng)使用Core绽慈。

  • 如果您希望以更以模式為中心的視圖(如SQL中使用的)查看數(shù)據(jù)恨旱,請(qǐng)使用Core。

  • 如果您有不需要業(yè)務(wù)對(duì)象的數(shù)據(jù)坝疼,請(qǐng)使用Core搜贤。

  • 如果您將數(shù)據(jù)視為業(yè)務(wù)對(duì)象,請(qǐng)使用ORM钝凶。

  • 如果您正在構(gòu)建一個(gè)快速原型仪芒,請(qǐng)使用ORM。

  • 如果您的需求組合確實(shí)可以利用業(yè)務(wù)對(duì)象和其他與問(wèn)題領(lǐng)域無(wú)關(guān)的數(shù)據(jù)耕陷,請(qǐng)同時(shí)使用它們!

現(xiàn)在掂名,您已經(jīng)了解了SQLAlchemy的結(jié)構(gòu)以及Core和ORM之間的區(qū)別,我們已經(jīng)準(zhǔn)備好安裝并開(kāi)始使用SQLAlchemy來(lái)連接數(shù)據(jù)庫(kù)哟沫。

SQLAlchemy的安裝

默認(rèn)情況下饺蔑,SQLAlchemy將支持SQLite3,不需要額外的驅(qū)動(dòng)程序;但是嗜诀,需要一個(gè)使用標(biāo)準(zhǔn)Python DBAPI (PEP-249)規(guī)范的附加數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序來(lái)連接到其他數(shù)據(jù)庫(kù)猾警。這些DBAPI為每個(gè)數(shù)據(jù)庫(kù)服務(wù)器使用的dialect提供了基礎(chǔ),并且通常支持在不同數(shù)據(jù)庫(kù)服務(wù)器和版本中看到的獨(dú)特特性裹虫。雖然許多數(shù)據(jù)庫(kù)可以使用多個(gè)dbapi肿嘲,但是下面的說(shuō)明主要針對(duì)最常見(jiàn)的數(shù)據(jù)庫(kù):

PostgreSQL

Psycopg2提供了對(duì)PostgreSQL版本和特性的廣泛支持融击,可以與pip install Psycopg2一起安裝筑公。

MySQL

PyMySQL是我用來(lái)連接MySQL數(shù)據(jù)庫(kù)服務(wù)器的首選Python庫(kù)。它可以與pip安裝pymysql一起安裝尊浪。SQLAlchemy中的MySQL支持要求MySQL版本4.1或更高匣屡,這是由于該版本之前密碼的工作方式封救。此外,如果特定的語(yǔ)句類型僅在MySQL的某個(gè)版本中可用捣作,SQLAlchemy不提供在語(yǔ)句不可用的MySQL版本上使用這些語(yǔ)句的方法誉结。如果SQLAlchemy中的某個(gè)組件或函數(shù)在您的環(huán)境中不起作用,那么檢查MySQL文檔是很重要的券躁。

其他類型

SQLAlchemy還可以與Drizzle惩坑、Firebird、Oracle也拜、Sybase和Microsoft SQL Server一起使用以舒。該社區(qū)還為許多其他數(shù)據(jù)庫(kù)提供了外部dialect,如IBM DB2慢哈、Informix蔓钟、Amazon Redshift、EXASolution卵贱、SAP SQL Anywhere滥沫、Monet等。

現(xiàn)在可以安裝SQLAlchemy

pip install -U sqlalchemy

檢查安裝結(jié)果:目前最新的發(fā)行版本是1.2.15键俱,

>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.2.15'
>>>

連接一個(gè)數(shù)據(jù)庫(kù)

要連接到數(shù)據(jù)庫(kù)兰绣,我們需要?jiǎng)?chuàng)建一個(gè)SQLAlchemy引擎。SQLAlchemy引擎創(chuàng)建到數(shù)據(jù)庫(kù)的公共接口來(lái)執(zhí)行SQL語(yǔ)句编振。它通過(guò)包裝數(shù)據(jù)庫(kù)連接池和dialect來(lái)實(shí)現(xiàn)這一點(diǎn)狭魂,這些連接池和dialect可以協(xié)同工作,提供對(duì)后端數(shù)據(jù)庫(kù)的統(tǒng)一訪問(wèn)党觅。這使我們的Python代碼不必?fù)?dān)心數(shù)據(jù)庫(kù)或dbapi之間的差異雌澄。

SQLAlchemy提供了一個(gè)函數(shù)來(lái)為我們創(chuàng)建一個(gè)引擎,該引擎提供了一個(gè)連接字符串和一些額外的關(guān)鍵字參數(shù)杯瞻。連接字符串是一種特殊格式的字符串镐牺,它提供:

  • 數(shù)據(jù)庫(kù)類型(Postgres, MySQL等)

  • 除非數(shù)據(jù)庫(kù)類型是默認(rèn)的(Psycopg2、PyMySQL等)魁莉,否則使用dialect睬涧。

  • 可選身份驗(yàn)證細(xì)節(jié)(用戶名和密碼)

  • 數(shù)據(jù)庫(kù)的位置(數(shù)據(jù)庫(kù)服務(wù)器的文件或主機(jī)名)

  • 可選的數(shù)據(jù)庫(kù)服務(wù)器端口,不指定則根據(jù)所選數(shù)據(jù)庫(kù)類型連接其常規(guī)的默認(rèn)端口

  • 可選的數(shù)據(jù)庫(kù)名稱

SQLite數(shù)據(jù)庫(kù)連接字符串讓我們表示特定的文件或存儲(chǔ)位置旗唁。示例P-1定義了一個(gè)名為cookies的SQLite數(shù)據(jù)庫(kù)文件畦浓。db通過(guò)第二行中的相對(duì)路徑存儲(chǔ)在當(dāng)前目錄中,第三行是內(nèi)存中的數(shù)據(jù)庫(kù)检疫,第四行(Unix)和第五行(Windows)是文件的完整路徑讶请。在Windows上,連接字符串看起來(lái)像engine4;除非您使用原始字符串(r”)屎媳,否則需要使用\進(jìn)行適當(dāng)?shù)淖址D(zhuǎn)義夺溢。

示例P-1:創(chuàng)建一個(gè)連接SQLite的engine

from sqlalchemy import create_engine 
engine = create_engine('sqlite:///cookies.db') 
engine2 = create_engine('sqlite:///:memory:')
engine3 = create_engine('sqlite:////home/cookiemonster/cookies.db') 
engine4 = create_engine('sqlite:///c:\\Users\\cookiemonster\\cookies.db')

提示:create_engine只是創(chuàng)建了一個(gè)engine實(shí)例论巍,但是它并不會(huì)立即去連接數(shù)據(jù)庫(kù),只有在需要連接數(shù)據(jù)庫(kù)的操作觸發(fā)后风响,engine才會(huì)去連接數(shù)據(jù)庫(kù)嘉汰,譬如一個(gè)查詢操作。

讓我們?yōu)槊麨閙ydb的本地PostgreSQL數(shù)據(jù)庫(kù)創(chuàng)建一個(gè)引擎状勤。我們首先從基本sqlalchemy包導(dǎo)入create_engine函數(shù)鞋怀。接下來(lái),我們將使用該函數(shù)構(gòu)造一個(gè)引擎實(shí)例持搜。在示例P-2中接箫,您會(huì)注意到我使用postgresql+psycopg2作為連接字符串的引擎和dialect組件,即使只使用postgres也可以工作朵诫。這是因?yàn)槲腋矚g顯式而不是隱式辛友,就像Python之禪推薦的那樣。

示例P-2:創(chuàng)建一個(gè)連接本地PostgreSQL的engine

from sqlalchemy import create_engine 
engine = create_engine('postgresql+psycopg2://username:password@localhost:5432/mydb')

現(xiàn)在讓我們看一下遠(yuǎn)程服務(wù)器上的MySQL數(shù)據(jù)庫(kù)剪返。您將注意到废累,在示例P-3中,在連接字符串之后脱盲,我們有一個(gè)關(guān)鍵字參數(shù)pool_recycle邑滨,用于定義循環(huán)使用連接的頻率。

示例P-3:創(chuàng)建一個(gè)連接遠(yuǎn)程MySQL數(shù)據(jù)庫(kù)的engine

from sqlalchemy import create_engine 
engine = create_engine('mysql+pymysql://cookiemonster:chocolatechip@mysql01.monster.'
                       'internal/cookies', pool_recycle=3600)

注意:默認(rèn)情況下钱反,MySQL會(huì)關(guān)閉空閑時(shí)間超過(guò)8小時(shí)的連接掖看。要解決這個(gè)問(wèn)題,在創(chuàng)建引擎時(shí)使用pool_recycle=3600面哥,如示例P-3所示哎壳。

一些在創(chuàng)建engine時(shí)可選的參數(shù)如下:

  • echo

    這將記錄引擎處理的操作,如SQL語(yǔ)句及其參數(shù)尚卫。它默認(rèn)為false归榕。

  • encoding

    這定義了SQLAlchemy使用的字符串編碼。它默認(rèn)為utf-8吱涉,大多數(shù)DBAPI默認(rèn)支持這種編碼刹泄。這并不定義后端數(shù)據(jù)庫(kù)本身使用的編碼類型。

  • isolation_level

    這指示SQLAlchemy使用特定的隔離級(jí)別怎爵。例如特石,帶有Psycopg2的PostgreSQL有READ COMMITTED、READ UNCOMMITTED鳖链、REPEATABLE READ姆蘸、SERIALIZABLE和AUTOCOMMIT,默認(rèn)情況下是READ COMMITTED。PyMySQL具有相同的選項(xiàng)乞旦,默認(rèn)為InnoDB數(shù)據(jù)庫(kù)的可重復(fù)讀取。

    注意:使用isolation_level關(guān)鍵字參數(shù)將為任何給定的DBAPI設(shè)置隔離級(jí)別题山。這與通過(guò)連接字符串中的鍵-值對(duì)(如支持該方法的Psycopg2)來(lái)實(shí)現(xiàn)相同兰粉。

  • pool_recyle

    這將定期回收或超時(shí)數(shù)據(jù)庫(kù)連接。由于前面提到的連接超時(shí)顶瞳,這對(duì)于MySQL非常重要玖姑。它的默認(rèn)值是-1,這意味著沒(méi)有超時(shí)慨菱。

一旦初始化了引擎焰络,就可以實(shí)際打開(kāi)到數(shù)據(jù)庫(kù)的連接。這是通過(guò)調(diào)用引擎上的connect()方法實(shí)現(xiàn)的符喝,如下所示:

from sqlalchemy import create_engine 
engine = create_engine('mysql+pymysql://cookiemonster:chocolatechip'
                       '@mysql01.monster.internal/cookies', pool_recycle=3600) 
connection = engine.connect()

現(xiàn)在我們已經(jīng)有了數(shù)據(jù)庫(kù)連接闪彼,可以開(kāi)始使用SQLAlchemy Core或ORM。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末协饲,一起剝皮案震驚了整個(gè)濱河市畏腕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茉稠,老刑警劉巖描馅,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異而线,居然都是意外死亡铭污,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)膀篮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)嘹狞,“玉大人,你說(shuō)我怎么就攤上這事誓竿〉笕蓿” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵烤黍,是天一觀的道長(zhǎng)知市。 經(jīng)常有香客問(wèn)我,道長(zhǎng)速蕊,這世上最難降的妖魔是什么嫂丙? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮规哲,結(jié)果婚禮上跟啤,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好隅肥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布竿奏。 她就那樣靜靜地躺著,像睡著了一般腥放。 火紅的嫁衣襯著肌膚如雪泛啸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,165評(píng)論 1 299
  • 那天秃症,我揣著相機(jī)與錄音候址,去河邊找鬼。 笑死种柑,一個(gè)胖子當(dāng)著我的面吹牛岗仑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播聚请,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼荠雕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了驶赏?” 一聲冷哼從身側(cè)響起舞虱,我...
    開(kāi)封第一講書(shū)人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎母市,沒(méi)想到半個(gè)月后矾兜,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡患久,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年椅寺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蒋失。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡返帕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篙挽,到底是詐尸還是另有隱情荆萤,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布铣卡,位于F島的核電站链韭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏煮落。R本人自食惡果不足惜敞峭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蝉仇。 院中可真熱鬧旋讹,春花似錦殖蚕、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至鞭呕,卻和暖如春蛤育,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背琅拌。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工缨伊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留摘刑,地道東北人进宝。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像枷恕,于是被迫代替她去往敵國(guó)和親党晋。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353