Python的魔法ORM --《PonyORM教程》 3 實(shí)體繼承

實(shí)體繼承就是我們平時(shí)編程時(shí)用到的類(lèi)的繼承捶枢。不過(guò)由于ORM牽扯到數(shù)據(jù)在數(shù)據(jù)庫(kù)中的存儲(chǔ)問(wèn)題寝优,所以情況要復(fù)雜一些玩裙,常見(jiàn)的對(duì)于有繼承關(guān)系的類(lèi)處理方法一般是以下三種:

  1. 單表繼承模式 父類(lèi)和子類(lèi)的所有字段都保存在同一張表里。
  2. 具體表繼承模式 父類(lèi)和子類(lèi)的所有字段分別保存在自己的表里
  3. 聯(lián)表繼承模式 父類(lèi)的表記錄公共字段帝火,后代類(lèi)的表記錄自己的專用字段

django使用的是聯(lián)表繼承模式痕貌,sqlalchemy作為重量級(jí)的ORM實(shí)現(xiàn)了全部的3種繼承模式(牛逼胺缯帧!??????)舵稠,而pony選擇的是單表繼承模式超升。三種模式的優(yōu)缺點(diǎn)如下:

單表繼承模式

優(yōu)點(diǎn)

  • 由于所有的記錄都放在一張表里,所以查詢對(duì)象的時(shí)候哺徊,無(wú)需聯(lián)表查詢室琢,速度快
  • 有關(guān)系的父子類(lèi)之間不存在數(shù)據(jù)同步更新問(wèn)題。
  • 冗余字段少落追。

缺點(diǎn)

  • 不同類(lèi)的數(shù)據(jù)保存在一起盈滴,不方便剝離某個(gè)單獨(dú)的類(lèi)。
  • 由于不同的子類(lèi)可能有不同的字段定義轿钠,導(dǎo)致表中出現(xiàn)大量的Null值巢钓,雖然這并不會(huì)占用大量的空間病苗,但是對(duì)于某些類(lèi)型的強(qiáng)迫癥患者來(lái)說(shuō),這可能是一個(gè)不能忍的缺陷症汹。
  • 由于所有的類(lèi)的字段的定義都保存在一張表內(nèi)硫朦,在某種極端的情況下,這可能會(huì)達(dá)到數(shù)據(jù)庫(kù)的限制烈菌。不過(guò)一般情況下阵幸,這種限制都很高。比如mysql的最大列限制是4096芽世,最大行尺寸是65,535bytes
具體表繼承模式

優(yōu)點(diǎn)

  • 不同的類(lèi)都有自己專用的表,無(wú)需聯(lián)表查詢诡壁,速度快济瓢。
  • 每個(gè)類(lèi)的數(shù)據(jù)獨(dú)立存儲(chǔ)自己的表中,方便剝離妹卿, 靈活性高旺矾。

缺點(diǎn)

  • 冗余字段多,浪費(fèi)空間夺克。
  • 有關(guān)系的父子類(lèi)之間可能存在數(shù)據(jù)同步更新問(wèn)題箕宙。(依模型設(shè)計(jì)而定),要小心處理铺纽。

聯(lián)表繼承模式

優(yōu)點(diǎn)

  • 冗余字段少且沒(méi)有額外的Null值
  • 有關(guān)系的父子類(lèi)之間不存在數(shù)據(jù)同步更新問(wèn)題柬帕。

缺點(diǎn)

  • 子類(lèi)的數(shù)據(jù)需要聯(lián)表查詢,效率低狡门,這也是這種模式最大的問(wèn)題陷寝。
  • 不同類(lèi)的數(shù)據(jù)雖然保存在不同的表中,但由于每個(gè)表保存的都是部分?jǐn)?shù)據(jù)所以依然不方便剝離某個(gè)單獨(dú)的類(lèi)其馏。

演示一下

class Person(db.Entity):
    """人"""
    _table_ = "person"
    name = Required(str, max_len=40)
    # class_type = Discriminator(str)  # 定義一個(gè)鑒別器字段
class Customer(Person):
    """顧客"""
    member_level = Required(int, size=8, default=0)  # 會(huì)員卡級(jí)別
    # _discriminator_ = "customer" 鑒別標(biāo)識(shí)


class Sales(Person):
    """銷(xiāo)售員"""
    performance = Required(float, default=0.0)  # 銷(xiāo)售業(yè)績(jī)
    # _discriminator_ = "sales" 鑒別標(biāo)識(shí)


if __name__ == "__main__":
    db.drop_table(table_name="person", if_exists=True, with_all_data=True)  # 刪除表凤跑,演示實(shí)體聲明時(shí)用于快速清除舊表
    db.generate_mapping(create_tables=True)  # 生成實(shí)體,表和映射關(guān)系
    with db_session:
        person = Person(name="約翰")  # 創(chuàng)建一個(gè)Person對(duì)象的實(shí)例
        customer = Customer(name="瑪麗", member_level=1)  # 創(chuàng)建一個(gè)Customer對(duì)象的實(shí)例
        sales = Sales(name="喬治", performance=3000)  # 創(chuàng)建一個(gè)Sales對(duì)象的實(shí)例
        flush()  # 刷新叛复,這里的刷新是為了讓剛才創(chuàng)建的對(duì)象分配到id
        print("所有人員信息:" + " ".join([x for x in select(x.name for x in Person)]))  
        print("所有客戶信息:" + " ".join([x for x in select(x.name for x in Customer)]))  
        print("所有銷(xiāo)售員信息:" + " ".join([x for x in select(x.name for x in Sales)]))  
    pass

說(shuō)明

  • 只能在頂級(jí)的父類(lèi)中定義表名仔引,子類(lèi)表中不可重新定義表名
  • 父類(lèi)中可以自定義一個(gè)鑒別器字段,用于區(qū)別不同的類(lèi)褐奥,定義的方法上面代碼咖耘,要求是
    只要是Discriminator的實(shí)例就好了,可以是字符串抖僵,也可以是其他類(lèi)型鲤看,不過(guò),當(dāng)不是字符串的時(shí)候耍群,子類(lèi)必須定義discriminator字段(鑒別標(biāo)識(shí)义桂,用于確認(rèn)類(lèi)的數(shù)據(jù)在表中的唯一性)找筝,鑒別器字段不是必須定義的,系統(tǒng)會(huì)提供默認(rèn)值classtype
  • 子類(lèi)中可以定義discriminator(鑒別標(biāo)識(shí))字段慷吊,用于確認(rèn)字段的歸屬袖裕。定義時(shí),必須和頂級(jí)父類(lèi)中定義的Discriminator實(shí)例的類(lèi)型一致,鑒別標(biāo)識(shí)字段不是必須定義的溉瓶,系統(tǒng)會(huì)提把類(lèi)名作為默認(rèn)值急鳄。

執(zhí)行結(jié)果

Connected to pydev debugger (build 192.6603.34)
所有人員信息:約翰 瑪麗 喬治
所有客戶信息:瑪麗
所有銷(xiāo)售員信息:?jiǎn)讨?
Process finished with exit code 0

你可以注意到,由于Customer和Sales是Person的子類(lèi)堰酿,所以在添加Customer和Sales實(shí)例時(shí)疾宏,Person也增加了對(duì)應(yīng)的實(shí)例

屏幕截圖.png

請(qǐng)注意classtype是鑒別器字段,這里使用了默認(rèn)值類(lèi)名作鑒別標(biāo)識(shí)触创。

索引

  1. Python的魔法ORM --《PonyORM教程》 1.連接,聲明和查詢
  2. Python的魔法ORM --《PonyORM教程》 2 實(shí)體關(guān)系
  3. Python的魔法ORM --《PonyORM教程》 3 實(shí)體繼承
  4. Python的魔法ORM --《PonyORM教程》 4 高級(jí)定義和連接查詢
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末坎藐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哼绑,更是在濱河造成了極大的恐慌岩馍,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抖韩,死亡現(xiàn)場(chǎng)離奇詭異蛀恩,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)茂浮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)双谆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人励稳,你說(shuō)我怎么就攤上這事佃乘。” “怎么了驹尼?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵趣避,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我新翎,道長(zhǎng)程帕,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任地啰,我火速辦了婚禮愁拭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘亏吝。我一直安慰自己岭埠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著惜论,像睡著了一般许赃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上馆类,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天混聊,我揣著相機(jī)與錄音,去河邊找鬼乾巧。 笑死句喜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沟于。 我是一名探鬼主播咳胃,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼旷太!你這毒婦竟也來(lái)了拙绊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤泳秀,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后榄攀,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體嗜傅,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年檩赢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吕嘀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡贞瞒,死狀恐怖偶房,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情军浆,我是刑警寧澤棕洋,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站乒融,受9級(jí)特大地震影響掰盘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赞季,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一愧捕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧申钩,春花似錦次绘、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)管跺。三九已至,卻和暖如春钢猛,著一層夾襖步出監(jiān)牢的瞬間伙菜,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工命迈, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留贩绕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓壶愤,卻偏偏與公主長(zhǎng)得像淑倾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子征椒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345