1. 程式人生 > 其它 >多對多表操作

多對多表操作

多對多表操作

一、建立表

多對多的第三張表flask不能自動產生第三張表,需要自己手動建立第三張表,並設定表之間的關係

# model.py
import datetime
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index
from sqlalchemy.orm import relationship

Base = declarative_base()

# make_declarative_base
class Girl(Base):
    __tablename__ = 'girl'
    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)


class Boy(Base):
    __tablename__ = 'boy'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(64), unique=True, nullable=False)

    # 與生成表結構無關,僅用於查詢方便,放在哪個單表中都可以
    #                   關係表名  第三張表名          反向查詢欄位
    girl = relationship('Girl', secondary='boy2girl', backref='boys')

class Boy2Girl(Base):
    __tablename__ = 'boy2girl'
    id = Column(Integer, primary_key=True, autoincrement=True)
    girl_id = Column(Integer, ForeignKey('girl.id'))
    boy_id = Column(Integer, ForeignKey('boy.id'))
    
    
def init_db():
    """
    根據類建立資料庫表
    :return:
    """
    engine = create_engine(
        "mysql+pymysql://root:[email protected]:3306/db_flask?charset=utf8",
        max_overflow=0,  # 超過連線池大小外最多建立的連線
        pool_size=5,  # 連線池大小
        pool_timeout=30,  # 池中沒有執行緒最多等待的時間,否則報錯
        pool_recycle=-1  # 多久之後對執行緒池中的執行緒進行一次連線的回收(重置)
    )

    Base.metadata.create_all(engine)


def drop_db():
    """
    根據類刪除資料庫表
    :return:
    """
    engine = create_engine(
        "mysql+pymysql://root:[email protected]:3306/db_flask?charset=utf8",
        max_overflow=0,  # 超過連線池大小外最多建立的連線
        pool_size=5,  # 連線池大小
        pool_timeout=30,  # 池中沒有執行緒最多等待的時間,否則報錯
        pool_recycle=-1  # 多久之後對執行緒池中的執行緒進行一次連線的回收(重置)
    )

    Base.metadata.drop_all(engine)


if __name__ == '__main__':
    # 建立表
    init_db()

    # 刪除表
    # drop_db()

二、設定表之間的關係

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from model import Girl, Boy, Boy2Girl

engine = create_engine("mysql+pymysql://root:[email protected]:3306/db_flask", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine)
session = Session()

# 1. 新增資料
# 方式一
# 不會設定第三張表之間的關係,需要手動設定
session.add_all([
    Girl(name='girl1'),
    Girl(name='g2.girl2'),
    Boy(name='box1'),
    Boy(name='box2'),
])

# 手動新增第三張表之間的關係
boy_girl = Boy2Girl(girl_id=1, boy_id=2)
session.add(boy_girl)

# 方式二 正向查詢, 自動設定第三張表之間的關係
boy = Boy(name='b3')
boy.girl = [Girl(name='g3'), Girl(name='g4')]
session.add(boy)

# 方式三 反向查詢, 自動設定第三張表時間的關係
girl = Girl(name='girl5')
girl.boys = [Boy(name='boy4'), Boy(name='boy5')]
session.add(girl)


session.commit()

三、正反向查詢

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from model import Girl, Boy, Boy2Girl

engine = create_engine("mysql+pymysql://root:[email protected]:3306/db_flask", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine)
session = Session()
# 1. 使用relationship正向查詢

boy = session.query(Boy).filter(Boy.id == 3).first()

print(boy.name)
# 正向查詢
for girl in boy.girl:
    print(girl.id, girl.name)
    
# 2.反向查詢
girl = session.query(Girl).filter(Girl.id == 5).first()
print(girl.name)
# 反向查詢
for boy in girl.boys:
    print(boy.id, boy.name) 

四、總結

  • flask多對多的關係不能實現自動建立第三張表需要自己手動建立第三張表,並設定表之間的關係
  • 通過正、反向查詢實現自動為其第三張表新增資料
  • 切記當使用正反向查詢的時候,注意查詢的欄位是包含一個值還是一個值,也就是查詢表之間的關係>
在當下的階段,必將由程式設計師來主導,甚至比以往更甚。