sqlalchemy 多對多關聯

2022-05-27 03:03:27 字數 4320 閱讀 9484

一、前言

現在來設計乙個能描述「圖書」與「作者」的關係的表結構,需求是:

一本書可以有好幾個作者一起出版

乙個作者可以寫好幾本書

此時你會發現,用之前學的外來鍵好像沒辦法實現上面的需求了,因為:

當然你更不可以像下面這樣幹,因為這樣就你就相當於有多條書的記錄了,太low b了,改書名還得都改。。。

這兩種情況,都發現資料時冗餘的,出現了很多重複的資訊,這樣可不行

二、多對多的表結構

2.1、表結構

說明:如果遇到這種情況的話,我們可以搞出一張中間表出來

說明:這樣就相當於通過book_m2m_author表完成了book表和author表之前的多對多關聯

from sqlalchemy import table,column,integer,string,date,foreignkey

from sqlalchemy.orm import relationship

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy import create_engine

base = declarative_base() #建立orm基類

book_m2m_author = table("book_m2m_author",base.metadata,

column("id",integer,primary_key=true),

column('books_id',integer,foreignkey("books.id")),

column('authors_id',integer,foreignkey("authors.id")))

class book(base):

__tablename__ = "books"

id = column(integer,primary_key=true)

name = column(string(64))

pub_date = column(date)

authors = relationship("author",secondary=book_m2m_author,backref="books")

def __repr__(self):

return self.name

class author(base):

__tablename__ = "authors"

id = column(integer,primary_key=true)

name = column(string(32))

def __repr__(self):

return self.name

engine = create_engine("mysql+pymysql:",

encoding="utf-8")

base.metadata.create_all(engine)

注意了,這裡面有這種建立表結構方式,跟我們之前的不太一樣:

book_m2m_author = table("book_m2m_author",base.metadata,

column("id",integer,primary_key=true),

column('books_id',integer,foreignkey("books.id")),

column('authors_id',integer,foreignkey("authors.id")))

這張表對使用者來講的是不需要關心的,是orm自動幫你維護的,在自動幫你維護的情況下,不需要操作它了,不需要搞對映關係了,通過這個命令table 去建立乙個表,這張表通過外來鍵已經幫我們關聯了,但是通過orm的查詢的時候,我們還是需要建立下面的關係的:

authors = relationship("author",secondary=book_m2m_author,backref="books")
這一句話表名,在orm查詢的時候,還需要orm記憶體物件的乙個級別的對映,如果沒有具體制定,沒有人知道第三張表book_m2m_author的存在,因為第3張表主動關聯其他兩張表。

from day12.orm_m2m import m2m_table

from sqlalchemy.orm import sessionmaker

session_class = sessionmaker(bind=m2m_table.engine)

session = session_class()

b1 = m2m_table.book(name="python",pub_date="2017-08-08")

b2 = m2m_table.book(name="sb",pub_date="2017-10-08")

b3 = m2m_table.book(name="zb",pub_date="2017-11-08")

a1 = m2m_table.author(name="sbhong")

a2 = m2m_table.author(name="sgaogao")

a3 = m2m_table.author(name="dbhong")

b1.authors = [a1,a3]

b2.authors = [a1,a2,a3]

session.add_all([b1,b2,b3,a1,a2,a3])

session.commit()

from day12.orm_m2m import m2m_table

from sqlalchemy.orm import sessionmaker

session_class = sessionmaker(bind=m2m_table.engine)

session = session_class()

authors_obj = session.query(m2m_table.author).filter_by(name="sbhong").first()

print(authors_obj.books) #通過books反查出books表中的資料

book_obj = session.query(m2m_table.book).filter(m2m_table.book.id==2).first()

print(book_obj.authors) #通過authors反查出authors表中的資料

session.commit()

#輸出[python, sb]

[dbhong, sgaogao, sbhong]

2.6、刪除資料刪除資料時不用管boo_m2m_authors , sqlalchemy會自動幫你把對應的資料刪除

通過書刪除作者

author_obj =s.query(author).filter_by(name="jack").first()

book_obj = s.query(book).filter_by(name="跟alex學把妹").first()

book_obj.authors.remove(author_obj) #從一本書裡刪除乙個作者

s.commit()

直接刪除作者刪除作者時,會把這個作者跟所有書的關聯關係資料也自動刪除

author_obj =s.query(author).filter_by(name="alex").first()

# print(author_obj.name , author_obj.books)

s.delete(author_obj)

s.commit()

2.7、處理中文

sqlalchemy設定編碼字符集一定要在資料庫訪問的url上增加charset=utf8,否則資料庫的連線就不是utf8的編碼格式

eng = create_engine('mysql://root:root@localhost:3306/test2?charset=utf8',echo=true)

hibernate多對多關聯

一 配置雙向多對多關聯 以project類 專案 和emp類 員工 為例 1 建立project類,並需要定義集合型別的emp屬性 public class project public void setpid integer pid public string getpname public vo...

thinkphp 多對多關聯模型

先建立乙個模型 class usermodel extends relationmodel 然後建立資料庫。分別建立三張表 think user think group think user group user 表裡userid username欄位 group 表裡groupid email欄位...

Hibernate多對多關聯關係

今天遇到乙個問題 有乙個的類reckoning,乙個類accountitem。這兩個類之間的關係時多對多的關聯關係。一開始是由accountitem來維護關聯關係的,也就是reckoning.hbm.xml檔案中的如下 將inverse的值設為true.set name accountitems t...