sqlalchemy操作手冊(cè)

orm操作是所有完整軟件中后端處理最重要的一部分悟衩,主要完成了后端程序和數(shù)據(jù)庫之間的數(shù)據(jù)同步和持久化的操作藕施,本文基于sqlalchemy官方文檔進(jìn)行整理,完成sqlalchemy的核心操作

目錄

什么是ORM?

常見的ORM操作流程和步驟?

sqlalchemy基礎(chǔ)操作?

1 什么是ORM?

2 常見的ORM操作流程和步驟?

3 sqlalchemy基礎(chǔ)操作?

3.1. 安裝 3

3.2. 連接引擎 3

3.3. 連接會(huì)話 4

3.4. ORM之Object操作 4

3.4.1. 基礎(chǔ)類 4

3.4.2. 數(shù)據(jù)類型創(chuàng)建 5

3.4.3. 數(shù)據(jù)類型映射操作 5

3.5. 增加和更新 6

3.6. 查詢對(duì)象Query 6

3.6.1. 常規(guī)查詢query 6

3.6.2. 指定排序查詢 6

3.6.3. 指定列查詢 7

3.6.4. 指定列屬性別名 7

3.6.5. 指定類型別名 7

3.6.6. 切片查詢 7

3.7. 條件篩選filter 7

3.7.1. 等值條件——equals / not equals 8

3.7.2. 模糊條件——like 8

3.7.3. 范圍條件——in / not in 8

3.7.4. 空值條件——is null / is not null 8

3.7.5. 并且條件——AND 8

3.7.6. 或者條件——OR 9

3.7.7. SQL語句查詢 9

3.8. 查詢結(jié)果 9

3.8.1. all()函數(shù)返回查詢列表 9

3.8.2. filter()函數(shù)返回單項(xiàng)數(shù)據(jù)的列表生成器 9

3.8.3. one()/one_or_none()/scalar()返回單獨(dú)的一個(gè)數(shù)據(jù)對(duì)象 9

1. 什么是ORM

ORM:Object Relation Mapping督暂,最初主要描述的是程序中的Object對(duì)象和關(guān)系型數(shù)據(jù)庫中Rlation關(guān)系(表)之間的映射關(guān)系辜限,目前來說也是描述程序中對(duì)象和數(shù)據(jù)庫中數(shù)據(jù)記錄之間的映射關(guān)系的統(tǒng)稱皇拣,是一種進(jìn)行程序和數(shù)據(jù)庫之間數(shù)據(jù)持久化的一種編程思想。

2. 常見的ORM操作流程和步驟

常規(guī)情況下薄嫡,軟件程序中的ORM操作主要有四個(gè)操作場景:增氧急、刪、改毫深、查

核心操作一般會(huì)區(qū)分為:增刪改态蒂、查詢

增刪改操作

增加操作:程序中存在的一個(gè)對(duì)象Object數(shù)據(jù),通過[ORM]核心模塊進(jìn)行增加的函數(shù)定義將對(duì)象保存到數(shù)據(jù)庫的操作過程费什;如~注冊(cè)操作中钾恢,通過用戶輸入的賬號(hào)密碼等信息創(chuàng)建了一個(gè)獨(dú)立的對(duì)象,通過add()函數(shù)將對(duì)象增加保存到數(shù)據(jù)庫中鸳址,數(shù)據(jù)庫中就存在用戶這個(gè)對(duì)象數(shù)據(jù)了瘩蚪。

修改操作:程序中存在的一個(gè)對(duì)象Object數(shù)據(jù),有自己的id編號(hào)(可以是程序中自行賦值定義稿黍、更多的操作是從數(shù)據(jù)庫中查詢出來存在的一個(gè)對(duì)象)疹瘦,通過[ORM]核心模塊進(jìn)行修改函數(shù)的定義將對(duì)象改變的數(shù)據(jù)更新到數(shù)據(jù)庫中已經(jīng)存在的記錄中的過程;如~用戶更改登錄密碼操作時(shí)巡球,根據(jù)程序中查詢得到的一個(gè)用戶[id編號(hào)言沐、賬號(hào)、密碼酣栈、..]险胰,在程序中通過改變其密碼屬性數(shù)據(jù),然后通過update()函數(shù)將改變的數(shù)據(jù)更新保存到數(shù)據(jù)庫中矿筝,數(shù)據(jù)庫中原來的數(shù)據(jù)就發(fā)生了新的改變起便。

刪除操作:程序中存在的一個(gè)對(duì)象或者已知的id編號(hào),通過主鍵編號(hào)或者對(duì)象的任意屬性進(jìn)行數(shù)據(jù)庫中數(shù)據(jù)記錄的刪除的操作過程窖维;如~管理員刪除某個(gè)會(huì)員賬號(hào)的操作榆综,通過獲取要?jiǎng)h除會(huì)員的賬號(hào),然后通過delete()函數(shù)將要?jiǎng)h除的會(huì)員信息告知數(shù)據(jù)庫執(zhí)行刪除操作铸史,數(shù)據(jù)庫中的某條存在的數(shù)據(jù)記錄就被刪除掉了鼻疮。

3. sqlalchemy基礎(chǔ)操作

ORM操作在實(shí)際項(xiàng)目中的應(yīng)用非常多,涉及到的框架也是根據(jù)不同的項(xiàng)目有不同的處理模塊琳轿,不過操作流程和步驟都是大同小異基本沒有什么太大變化判沟,唯一需要注意的就是在實(shí)際操作過程中你要使用的ORM框架的處理性能和是否支持事務(wù)震贵、是否支持分布式等特性來進(jìn)行確定使用哪個(gè)ORM框架進(jìn)行操作,一般在python程序中ORM操作都是對(duì)mysqldb和pymysql這樣的底層模塊進(jìn)行的封裝處理水评。例如文章中要講解的sqlalchemy就是底層封裝mysqldb的實(shí)現(xiàn)猩系,不過我們的在使用過程中需要使用pymysql進(jìn)行替代。

3.1. 安裝

首先確保你的PC已經(jīng)具備了完善的python開發(fā)環(huán)境

安裝sqlalchemy中燥,執(zhí)行如下命令使用pip安裝即可

$ pip install sqlalchemy

或者執(zhí)行如下命令通過easy_install進(jìn)行安裝

$ easy_install sqlalchemy

安裝完成之后寇甸,可以通過引入sqlalchemy進(jìn)行版本查看,確認(rèn)sqlalchemy安裝成功

>>> import sqlalchemy>>> sqlalchemy.__version__'1.2.0b3'

3.2. 連接引擎

使用sqlalchemy進(jìn)行數(shù)據(jù)庫操作疗涉,首先我們需要建立一個(gè)指定數(shù)據(jù)庫的連接引擎對(duì)象

建立引擎對(duì)象的方式被封裝在了sqlalchemy.create_engine函數(shù)中拿霉,通過指定的數(shù)據(jù)庫連接信息就可以進(jìn)行創(chuàng)建

創(chuàng)建數(shù)據(jù)庫連接引擎時(shí)參數(shù)設(shè)置語法:

dialect[+driver]://user:password@host/dbname[?key=value..]# 引入建立引擎的模塊from sqlalchemy import create_engine# 創(chuàng)建一個(gè)和mysql數(shù)據(jù)庫之間的連接引擎對(duì)象engine = create_engine("mysql://root:root@localhost/py1709",

encoding="utf-8", echo=True)

指定的數(shù)據(jù)庫連接字符串表示了目標(biāo)數(shù)據(jù)庫的配置信息;encoding配置參數(shù)指定了和和數(shù)據(jù)庫之間交換的數(shù)據(jù)的編碼方式咱扣,同時(shí)echo參數(shù)表示隨時(shí)在控制臺(tái)展示和數(shù)據(jù)庫之間交互的各種信息

create_engine()函數(shù)返回的是sqlalchemy最核心的接口之一绽淘,該引擎對(duì)象會(huì)根據(jù)開發(fā)人員指定的數(shù)據(jù)庫進(jìn)行對(duì)應(yīng)的sql api的調(diào)用處理

連接postgresql數(shù)據(jù)庫:

engine = create_engine("postgresql://scott:tiger@localhost/test")

連接mysql數(shù)據(jù)庫:

engine = create_engine("mysql://scott:tiger@hostname/dbname",

encoding='utf-8', echo=True)

其他連接方式請(qǐng)參考官方文檔:http://docs.sqlalchemy.org/en/latest/

3.3. 連接會(huì)話

創(chuàng)建了數(shù)據(jù)庫連接引擎對(duì)象之后,我們需要獲取和指定數(shù)據(jù)庫之間的連接闹伪,通過連接進(jìn)行數(shù)據(jù)庫中數(shù)據(jù)的增刪改查操作沪铭,和數(shù)據(jù)庫的連接我們稱之為和指定數(shù)據(jù)庫之間的會(huì)話,通過指定的一個(gè)模塊

sqlalchemy.sessionmaker進(jìn)行創(chuàng)建# 引入創(chuàng)建session連接會(huì)話需要的處理模塊from sqlalchemy.orm import sessionmaker# 創(chuàng)建一個(gè)連接會(huì)話對(duì)象偏瓤;需要指定是和那個(gè)數(shù)據(jù)庫引擎之間的會(huì)話Session = sessionmaker(bind=engine)session = Session()# 接下來~就可以用過session會(huì)話進(jìn)行數(shù)據(jù)庫的數(shù)據(jù)操作了杀怠。

PS:如果在創(chuàng)建會(huì)話的時(shí)候還沒有指定數(shù)據(jù)庫引擎,可以通過如下的方式完成會(huì)話操作

Session = sessionmaker()..Session.configure(bind=engine)session = Session()..

3.4. ORM之Object操作

我們的程序中的對(duì)象要使用sqlalchemy的管理厅克,實(shí)現(xiàn)對(duì)象的orm操作赔退,就需要按照框架指定的方式進(jìn)行類型的創(chuàng)建操作,sqlalchemy封裝了基礎(chǔ)類的聲明操作和字段屬性的定義限制方式证舟,開發(fā)人員要做的事情就是引入需要的模塊并在創(chuàng)建對(duì)象的時(shí)候使用它們即可

基礎(chǔ)類封裝在sqlalchemy.ext.declarative.declarative_base模塊中

字段屬性的定義封裝在sqlalchemy模塊中硕旗,通過sqlalchemy.Column定義屬性,通過封裝的Integer女责、String漆枚、Float等定義屬性的限制

3.4.1. 基礎(chǔ)類

創(chuàng)建基礎(chǔ)類的方式如下:

# 引入需要的模塊from sqlalchemy.ext.declarative import declarative_base# 創(chuàng)建基礎(chǔ)類BaseModel = declarative_base()

3.4.2. 數(shù)據(jù)類型創(chuàng)建

創(chuàng)建數(shù)據(jù)模型的操作

# 引入需要的模塊from sqlalchemy import Column, String, Integer# 創(chuàng)建用戶類型class User(BaseModel):? ? # 定義和指定數(shù)據(jù)庫表之間的關(guān)聯(lián)? ? __tabelname__ = “user”? ? # 創(chuàng)建字段類型? ? id = Column(Integer, primary_key=True)? ? name = Column(String(50))? ? age = Column(Integer)

PS:定義的數(shù)據(jù)類型必須繼承自之前創(chuàng)建的BaseModel,同時(shí)通過指定tablename確定和數(shù)據(jù)庫中某個(gè)數(shù)據(jù)表之間的關(guān)聯(lián)關(guān)系鲤竹,指定某列類型為primary_key設(shè)定的主鍵浪读,其他就是通過Column指定的自定義屬性了。

sqlalchemy會(huì)根據(jù)指定的tablename和對(duì)應(yīng)的Column列字段構(gòu)建自己的accessors訪問器對(duì)象辛藻,這個(gè)過程可以成為instrumentation,經(jīng)過instrumentation映射的類型既可以進(jìn)行數(shù)據(jù)庫中數(shù)據(jù)的操作了互订。

3.4.3. 數(shù)據(jù)類型映射操作

完成了類的聲明定義之后吱肌,Declarative會(huì)通過python的metaclass對(duì)當(dāng)前類型進(jìn)行操作,根據(jù)定義的數(shù)據(jù)類型創(chuàng)建table對(duì)象仰禽,構(gòu)建程序中類型和數(shù)據(jù)庫table對(duì)象之間的映射mapping關(guān)系

通過類型對(duì)象的metadata可以實(shí)現(xiàn)和數(shù)據(jù)庫之間的交互氮墨,有需要時(shí)可以通過metadata發(fā)起create table操作纺蛆,通過Base.metadata.create_all()進(jìn)行操作,該操作會(huì)檢查目標(biāo)數(shù)據(jù)庫中是否有需要?jiǎng)?chuàng)建的表规揪,不存在的情況下創(chuàng)建對(duì)應(yīng)的表

..if __name__ == “__main__”:Base.metadata.create_all()..

3.5. 增加和更新

下面就是核心的數(shù)據(jù)對(duì)象的處理了桥氏,在程序代碼中根據(jù)定義的數(shù)據(jù)類型創(chuàng)建對(duì)象的方式比較簡單,執(zhí)行如下的操作創(chuàng)建一個(gè)對(duì)象:

$ user = User(name=”tom”, age=18)$ print(user.name)tom

$ print(user.id)None

通過會(huì)話對(duì)象將對(duì)象數(shù)據(jù)持久化到數(shù)據(jù)庫的操作

$ session.add(user)$ print(user.id)None$ session.commit()$ print(user.id)1

3.6. 查詢對(duì)象Query

Session是sqlalchemy和數(shù)據(jù)庫交互的橋梁猛铅,Session提供了一個(gè)Query對(duì)象實(shí)現(xiàn)數(shù)據(jù)庫中數(shù)據(jù)的查詢操作

3.6.1. 常規(guī)查詢query

直接指定類型進(jìn)行查詢

user_list = session.query(User)for user in user_list:? ? print(user.name)

3.6.2. 指定排序查詢

通過類型的屬性指定排序方式

user_list = session.query(User).order_by(User.id) # 默認(rèn)順序user_list = session.query(User).order_by(-User.id) # 指定倒序user_list = session.query(User).order_by(-User.id, User.name) # 多個(gè)字段

3.6.3. 指定列查詢

指定查詢數(shù)據(jù)對(duì)象的屬性字支,查詢目標(biāo)數(shù)據(jù)

user_list = session.query(User, User.name).all()for u in user_list:? ? print(u.User, u.name)

3.6.4. 指定列屬性別名

對(duì)于名稱較長的字段屬性,可以指定名稱在使用時(shí)簡化操作

user_list = session.query(Usre.name.label(‘n’)).all()for user in user_list:? ? print(user.n)

3.6.5. 指定類型別名

對(duì)于類型名稱較長的情況奸忽,同樣可以指定別名進(jìn)行處理

from sqlalchemy.orm import aliased

user_alias = aliased(User, name=’u_alias’)user_list = session.query(u_alias, u_alias.name).all()for u in user_list:? ? print(u.u_alias, u.name)

3.6.6. 切片查詢

對(duì)于經(jīng)常用于分頁操作的切片查詢堕伪,在使用過程中直接使用python內(nèi)置的切片即可

user_list = session.query(User).all()[1:3]..

3.7. 條件篩選filter

前一節(jié)中主要是對(duì)于數(shù)據(jù)查詢對(duì)象query有一個(gè)比較直觀的感受和操作,在實(shí)際使用過程中經(jīng)常用到條件查詢栗菜,主要通過filter和filter_by進(jìn)行操作欠雌,重點(diǎn)講解使用最為頻繁的filter條件篩選函數(shù)

3.7.1. 等值條件——equals / not equals

# equalssession.query(User).filter(User.id == 1) # 相等判斷# not equalssession.query(User).filter(User.name != ‘tom’)# 不等判斷

3.7.2. 模糊條件——like

session.query(User).filter(User.name.like(‘%tom%’))

3.7.3. 范圍條件——in / not in

# INsession.query(User).filter(User.id.in_([1,2,3,4]))session.query(User).filter(User.name.in_([? ? session.query(User.name).filter(User.id.in_[1,2,3,4])]))# NOT INsession.query(User).filter(~User.id.in_([1,2,3]))

3.7.4. 空值條件——is null / is not null

# IS NULLsession.query(User).filter(User.name == None)session.query(User).filter(User.name.is_(None)) # pep8# IS NOT NULLsession.query(User).filter(User.name != None)session.query(User).filter(User.name.isnot(None)) # pep8

3.7.5. 并且條件——AND

from sqlalchemy import and_

session.query(User).filter(User.name=’tom’).filter(User.age=12)session.query(User).filter(User.name=’tom’, User.age=12)session.query(User).filter(and_(User.name=’tom’, User.age=12))

3.7.6. 或者條件——OR

from sqlalchemy import or_

session.query(User).filter(or_(User.name=’tom’, User.name=’jerry’))

3.7.7. SQL語句查詢

某些特殊情況下,我們也可能在自己的程序中直接使用sql語句進(jìn)行操作

from sqlalchemy import text

session.query(User).from_statement(text(‘select * from users where name=:name and age=:age’)).params(name=’tom’, age=12).all()

3.8. 查詢結(jié)果

3.8.1. all()函數(shù)返回查詢列表

session.query(User).all()

[..]

3.8.2. filter()函數(shù)返回單項(xiàng)數(shù)據(jù)的列表生成器

session.query(User).filter(..)

<..>

3.8.3. one()/one_or_none()/scalar()返回單獨(dú)的一個(gè)數(shù)據(jù)對(duì)象

session.query(User).filter(..).one()/one_or_none()/scalar()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疙筹,一起剝皮案震驚了整個(gè)濱河市富俄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌而咆,老刑警劉巖蛙酪,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異翘盖,居然都是意外死亡桂塞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門馍驯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阁危,“玉大人,你說我怎么就攤上這事汰瘫】翊颍” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵混弥,是天一觀的道長趴乡。 經(jīng)常有香客問我,道長蝗拿,這世上最難降的妖魔是什么晾捏? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮哀托,結(jié)果婚禮上惦辛,老公的妹妹穿的比我還像新娘。我一直安慰自己仓手,他們只是感情好胖齐,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布玻淑。 她就那樣靜靜地躺著,像睡著了一般呀伙。 火紅的嫁衣襯著肌膚如雪补履。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天剿另,我揣著相機(jī)與錄音箫锤,去河邊找鬼。 笑死驰弄,一個(gè)胖子當(dāng)著我的面吹牛麻汰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播戚篙,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼五鲫,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了岔擂?” 一聲冷哼從身側(cè)響起位喂,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎乱灵,沒想到半個(gè)月后塑崖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痛倚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年规婆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蝉稳。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抒蚜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出耘戚,到底是詐尸還是另有隱情嗡髓,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布收津,位于F島的核電站饿这,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏撞秋。R本人自食惡果不足惜长捧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望部服。 院中可真熱鬧唆姐,春花似錦、人聲如沸廓八。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剧蹂。三九已至声功,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間宠叼,已是汗流浹背先巴。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冒冬,地道東北人伸蚯。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像简烤,于是被迫代替她去往敵國和親剂邮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容