python SQLAchemy多外鍵關聯

關聯同一張表的兩個字段

Customer表有2個字段都關聯了Address表python

建立表結構

orm_many_fk.py 只建立表結構mysql

from sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import create_engine
Base = declarative_base()


class Customer(Base):
    __tablename__ = 'customer'
    id = Column(Integer, primary_key=True)
    name = Column(String(64))

    billing_address_id = Column(Integer, ForeignKey("address.id"))
    shipping_address_id = Column(Integer, ForeignKey("address.id"))

    billing_address = relationship("Address",foreign_keys=[billing_address_id]) #foreign_keys 爲了區分哪一個外鍵對應哪一個字段
    shipping_address = relationship("Address",foreign_keys=[shipping_address_id])#


class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    street = Column(String(64))
    city = Column(String(64))
    state = Column(String(64))

    def __repr__(self):
        return self.street

engine = create_engine("mysql+pymysql://root:@localhost/test",encoding='utf-8')
Base.metadata.create_all(engine)  # 建立表結構

 

orm_api.py 添加數據。查詢sql

 

from day11 import orm_many_fk
from sqlalchemy.orm import sessionmaker

Session_class = sessionmaker(bind=orm_many_fk.engine)  # 建立與數據庫的會話session class ,注意,這裏返回給session的是個class,不是實例
Session = Session_class()  # 生成session實例 cursor

'''
addr1 = orm_many_fk.Address(street="Tiantongyuan",city="ChangPing",state="BeiJing")
addr2 = orm_many_fk.Address(street="Youryuan",city="ChaoYang",state="BeiJing")
addr3 = orm_many_fk.Address(street="baozipu",city="Haidian",state="BeiJing")
addr4 = orm_many_fk.Address(street="qingfeng",city="Haidian",state="BeiJing")

Session.add_all([addr1,addr2,addr3,addr4])
c1 = orm_many_fk.Customer(name="Alex",billing_address=addr1,shipping_address=addr2)
c2 = orm_many_fk.Customer(name="Jack",billing_address=addr3,shipping_address=addr3)

Session.add_all([c1,c2])
'''

obj = Session.query(orm_many_fk.Customer).filter(orm_many_fk.Customer.name=='alex').first()
print(obj.name,obj.billing_address,obj.shipping_address)

Session.commit()

 查詢結果數據庫

多對多關係

如今來設計一個能描述「圖書」與「做者」的關係的表結構,需求是api

  1. 一本書能夠有好幾個做者一塊兒出版
  2. 一個做者能夠寫好幾本書

 

 

此時你會發現,用以前學的外鍵好像沒辦法實現上面的需求了,由於session

固然你更不能夠像下面這樣幹,由於這樣就你就至關於有多條書的記錄了,太low b了,改書名還得都改。。。設計

 

那怎麼辦呢? 此時,咱們能夠再搞出一張中間表,就能夠了orm

這樣就至關於經過book_m2m_author表完成了book表和author表以前的多對多關聯。blog

建立表結構
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
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

book_m2m_author = Table('book_m2m_author', Base.metadata,
                        Column('book_id',Integer,ForeignKey('books.id')),
                        Column('author_id',Integer,ForeignKey('authors.id')),
                        )

class Book(Base):
    __tablename__ = 'books'
    id = Column(Integer,primary_key=True)
    name = Column(String(64))
    pub_date = Column(DATE)
    #正向查詢 經過 Book.authors 查book_m2m_author 關聯到Author 反向 Author.books 查book_m2m_author 關聯到Book
    authors = relationship('Author',secondary=book_m2m_author,backref='books') #secondary 聲明第三張表 book_m2m_author

    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://root:@localhost/test",encoding='utf-8')
Base.metadata.create_all(engine)  # 建立表結構

添加數據
from day11 import orm_m2m
from sqlalchemy.orm import sessionmaker

Session_class = sessionmaker(bind=orm_m2m.engine)  # 建立與數據庫的會話session class ,注意,這裏返回給session的是個class,不是實例
Session = Session_class()  # 生成session實例 cursor

b1 = orm_m2m.Book(name="lenarn python with Alex",pub_date="2014-01-02")
b2 = orm_m2m.Book(name="lenarn ZB with Alex",pub_date="2015-01-02")
b3 = orm_m2m.Book(name="lenarn paolu with Alex",pub_date="2016-01-02")

a1 = orm_m2m.Author(name="Alex")
a2 = orm_m2m.Author(name="Jack")
a3 = orm_m2m.Author(name="Rain")

b1.authors = [a1,a3]
b2.authors = [a2]
b3.authors = [a1,a2,a3]

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

Session.commit()

 

查詢某個做者下的書

根據做者查書sqlalchemy

author_obj = Session.query(orm_m2m.Author).filter(orm_m2m.Author.name =='alex').first()
print(author_obj.books)
print(author_obj.books[1].pub_date)

Session.commit()

 運行結果

[lenarn python with Alex, lenarn paolu with Alex]
2016-01-02

 根據書查做者

book_obj = Session.query(orm_m2m.Book).filter(orm_m2m.Book.id ==2).first()
print(book_obj.authors)
Session.commit()

  運行結果

[Rain, Jack, Alex]
相關文章
相關標籤/搜索