Flask系列教程(23)——SQLAlchemy的ORM(4)

SQLAlchemy的ORM(4)

如果想深入學(xué)習(xí)Flask量承,可以觀看這套免費(fèi)Flask教學(xué)視頻:零基礎(chǔ):Flask入門到項(xiàng)目實(shí)戰(zhàn)

表關(guān)系:

表之間的關(guān)系存在三種:一對(duì)一曙强、一對(duì)多、多對(duì)多算谈。而SQLAlchemy中的ORM也可以模擬這三種關(guān)系粉楚。因?yàn)橐粚?duì)一其實(shí)在SQLAlchemy中底層是通過一對(duì)多的方式模擬的,所以先來看下一對(duì)多的關(guān)系:

外鍵:

在Mysql中潘酗,外鍵可以讓表之間的關(guān)系更加緊密。而SQLAlchemy同樣也支持外鍵雁仲。通過ForeignKey類來實(shí)現(xiàn)仔夺,并且可以指定表的外鍵約束。相關(guān)示例代碼如下:

class Article(Base):
    __tablename__ = 'article'
    id = Column(Integer,primary_key=True,autoincrement=True)
    title = Column(String(50),nullable=False)
    content = Column(Text,nullable=False)
    uid = Column(Integer,ForeignKey('user.id'))

    def __repr__(self):
        return "<Article(title:%s)>" % self.title

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer,primary_key=True,autoincrement=True)
    username = Column(String(50),nullable=False)

外鍵約束有以下幾項(xiàng):

  1. RESTRICT:父表數(shù)據(jù)被刪除攒砖,會(huì)阻止刪除缸兔。默認(rèn)就是這一項(xiàng)。
  2. NO ACTION:在MySQL中吹艇,同RESTRICT惰蜜。
  3. CASCADE:級(jí)聯(lián)刪除。
  4. SET NULL:父表數(shù)據(jù)被刪除受神,子表數(shù)據(jù)會(huì)設(shè)置為NULL抛猖。

一對(duì)多:

拿之前的User表為例,假如現(xiàn)在要添加一個(gè)功能鼻听,要保存用戶的郵箱帳號(hào)财著,并且郵箱帳號(hào)可以有多個(gè),這時(shí)候就必須創(chuàng)建一個(gè)新的表撑碴,用來存儲(chǔ)用戶的郵箱撑教,然后通過user.id來作為外鍵進(jìn)行引用,先來看下郵箱表的實(shí)現(xiàn):

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer,primary_key=True)
    email_address = Column(String,nullable=False)
    # User表的外鍵醉拓,指定外鍵的時(shí)候伟姐,是使用的是數(shù)據(jù)庫表的名稱,而不是類名
    user_id = Column(Integer,ForeignKey('users.id'))
    # 在ORM層面綁定兩者之間的關(guān)系廉嚼,第一個(gè)參數(shù)是綁定的表的類名玫镐,
    # 第二個(gè)參數(shù)back_populates是通過User反向訪問時(shí)的字段名稱
    user = relationship('User',back_populates="addresses")

    def __repr__(self):
        return "<Address(email_address='%s')>" % self.email_address

# 重新修改User表,添加了addresses字段怠噪,引用了Address表的主鍵
class User(Base):
    __tablename__ = 'users'
    id = Column(Integer,primary_key=True)
    name = Column(String(50))
    fullname = Column(String(50))
    password = Column(String(100))
    # 在ORM層面綁定和`Address`表的關(guān)系
    addresses = relationship("Address",order_by=Address.id,back_populates="user")

其中恐似,在User表中添加的addresses字段,可以通過User.addresses來訪問和這個(gè)user相關(guān)的所有address傍念。在Address表中的user字段矫夷,可以通過Address.user來訪問這個(gè)user。達(dá)到了雙向綁定憋槐。表關(guān)系已經(jīng)建立好以后双藕,接下來就應(yīng)該對(duì)其進(jìn)行操作,先看以下代碼:

jack = User(name='jack',fullname='Jack Bean',password='gjffdd')
jack.addresses = [Address(email_address='jack@google.com'),
Address(email_address='j25@yahoo.com')]
session.add(jack)
session.commit()

首先阳仔,創(chuàng)建一個(gè)用戶忧陪,然后對(duì)這個(gè)jack用戶添加兩個(gè)郵箱,最后再提交到數(shù)據(jù)庫當(dāng)中,可以看到這里操作Address并沒有直接進(jìn)行保存嘶摊,而是先添加到用戶里面延蟹,再保存。

一對(duì)一:

一對(duì)一其實(shí)就是一對(duì)多的特殊情況叶堆,從以上的一對(duì)多例子中不難發(fā)現(xiàn)阱飘,一對(duì)應(yīng)的是User表,而多對(duì)應(yīng)的是Address虱颗,也就是說一個(gè)User對(duì)象有多個(gè)Address沥匈。因此要將一對(duì)多轉(zhuǎn)換成一對(duì)一,只要設(shè)置一個(gè)User對(duì)象對(duì)應(yīng)一個(gè)Address對(duì)象即可忘渔,看以下示例:

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer,primary_key=True)
    name = Column(String(50))
    fullname = Column(String(50))
    password = Column(String(100))
    # 設(shè)置uselist關(guān)鍵字參數(shù)為False
    addresses = relationship("Address",back_populates='addresses',uselist=False)

class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer,primary_key=True)
    email_address = Column(String(50))
    user_id = Column(Integer,ForeignKey('users.id')
    user = relationship('Address',back_populates='user')

從以上例子可以看到高帖,只要在User表中的addresses字段上添加uselist=False就可以達(dá)到一對(duì)一的效果。設(shè)置了一對(duì)一的效果后辨萍,就不能添加多個(gè)郵箱到user.addresses字段了棋恼,只能添加一個(gè):

user.addresses = Address(email_address='ed@google.com')

多對(duì)多:

多對(duì)多需要一個(gè)中間表來作為連接,同理在sqlalchemy中的orm也需要一個(gè)中間表锈玉。假如現(xiàn)在有一個(gè)Teacher和一個(gè)Classes表爪飘,即老師和班級(jí),一個(gè)老師可以教多個(gè)班級(jí)拉背,一個(gè)班級(jí)有多個(gè)老師师崎,是一種典型的多對(duì)多的關(guān)系,那么通過sqlalchemyORM的實(shí)現(xiàn)方式如下:

association_table = Table('teacher_classes',Base.metadata,
    Column('teacher_id',Integer,ForeignKey('teacher.id')),
    Column('classes_id',Integer,ForeignKey('classes.id'))
)
class Teacher(Base):
    __tablename__ = 'teacher'
    id = Column(Integer,primary_key=True)
    tno = Column(String(10))
    name = Column(String(50))
    age = Column(Integer)
    classes = relationship('Classes',secondary=association_table,back_populates='teachers')

class Classes(Base):
    __tablename__ = 'classes'
    id = Column(Integer,primary_key=True)
    cno = Column(String(10))
    name = Column(String(50))
    teachers = relationship('Teacher',secondary=association_table,back_populates='classes')

要?jiǎng)?chuàng)建一個(gè)多對(duì)多的關(guān)系表椅棺,首先需要一個(gè)中間表犁罩,通過Table來創(chuàng)建一個(gè)中間表。上例中第一個(gè)參數(shù)teacher_classes代表的是中間表的表名两疚,第二個(gè)參數(shù)是Base的元類床估,第三個(gè)和第四個(gè)參數(shù)就是要連接的兩個(gè)表,其中Column第一個(gè)參數(shù)是表示的是連接表的外鍵名诱渤,第二個(gè)參數(shù)表示這個(gè)外鍵的類型丐巫,第三個(gè)參數(shù)表示要外鍵的表名和字段。
創(chuàng)建完中間表以后勺美,還需要在兩個(gè)表中進(jìn)行綁定递胧,比如在Teacher中有一個(gè)classes屬性,來綁定Classes表赡茸,并且通過secondary參數(shù)來連接中間表缎脾。同理,Classes表連接Teacher表也是如此占卧。定義完類后遗菠,之后就是添加數(shù)據(jù)联喘,請(qǐng)看以下示例:

teacher1 = Teacher(tno='t1111',name='xiaotuo',age=10)
teacher2 = Teacher(tno='t2222',name='datuo',age=10)
classes1 = Classes(cno='c1111',name='english')
classes2 = Classes(cno='c2222',name='math')
teacher1.classes = [classes1,classes2]
teacher2.classes = [classes1,classes2]
classes1.teachers = [teacher1,teacher2]
classes2.teachers = [teacher1,teacher2]
session.add(teacher1)
session.add(teacher2)
session.add(classes1)
session.add(classes2)

如果想深入學(xué)習(xí)Flask,可以觀看這套免費(fèi)Flask教學(xué)視頻:零基礎(chǔ):Flask入門到項(xiàng)目實(shí)戰(zhàn)

</article>

版權(quán)聲明: https://blog.csdn.net/huangyong1314/article/details/80555065

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辙纬,一起剝皮案震驚了整個(gè)濱河市耸袜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌牲平,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件域滥,死亡現(xiàn)場(chǎng)離奇詭異纵柿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)启绰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門昂儒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人委可,你說我怎么就攤上這事渊跋。” “怎么了着倾?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵拾酝,是天一觀的道長。 經(jīng)常有香客問我卡者,道長蒿囤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任崇决,我火速辦了婚禮材诽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘恒傻。我一直安慰自己脸侥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布盈厘。 她就那樣靜靜地躺著睁枕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扑庞。 梳的紋絲不亂的頭發(fā)上譬重,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音罐氨,去河邊找鬼臀规。 笑死,一個(gè)胖子當(dāng)著我的面吹牛栅隐,可吹牛的內(nèi)容都是我干的塔嬉。 我是一名探鬼主播玩徊,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼谨究!你這毒婦竟也來了恩袱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤胶哲,失蹤者是張志新(化名)和其女友劉穎畔塔,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鸯屿,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡澈吨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寄摆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谅辣。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婶恼,靈堂內(nèi)的尸體忽然破棺而出桑阶,到底是詐尸還是另有隱情,我是刑警寧澤勾邦,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布蚣录,位于F島的核電站,受9級(jí)特大地震影響眷篇,放射性物質(zhì)發(fā)生泄漏包归。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一铅歼、第九天 我趴在偏房一處隱蔽的房頂上張望公壤。 院中可真熱鬧,春花似錦椎椰、人聲如沸厦幅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽确憨。三九已至,卻和暖如春瓤的,著一層夾襖步出監(jiān)牢的瞬間休弃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工圈膏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留塔猾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓稽坤,卻偏偏與公主長得像丈甸,于是被迫代替她去往敵國和親糯俗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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

  • 22年12月更新:個(gè)人網(wǎng)站關(guān)停睦擂,如果仍舊對(duì)舊教程有興趣參考 Github 的markdown內(nèi)容[https://...
    tangyefei閱讀 35,182評(píng)論 22 257
  • MySQL 命令大全 DDL(數(shù)據(jù)定義語句) CREATE TABLE/DATABASE ALTER TABLE/...
    子非初心閱讀 3,415評(píng)論 0 2
  • 轉(zhuǎn)載得湘,覺得這篇寫 SQLAlchemy Core,寫得非常不錯(cuò)顿仇。不過后續(xù)他沒寫SQLAlchemy ORM... ...
    非夢(mèng)nj閱讀 5,412評(píng)論 1 14
  • 鬼王和蜃蠡收編四大長老淘正,打著輔助閆中天完成大業(yè)的幌子欲統(tǒng)治江湖眾派,這樣以來臼闻,天下也將會(huì)是魔族的天下跪帝。 紫微和天樞...
    若水游心閱讀 423評(píng)論 0 0
  • 「APP評(píng)測(cè)」系列文章均出自集創(chuàng)堂會(huì)員之手,他們中有設(shè)計(jì)總監(jiān)些阅,也有入行不久的交互設(shè)計(jì)新人;闡述大部分客觀理性斑唬,難免...
    APP評(píng)測(cè)中心閱讀 8,883評(píng)論 0 6