多对多表操作

多对多表操作

一、创建表

多对多的第三张表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:root@127.0.0.1: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:root@127.0.0.1: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:root@127.0.0.1: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:root@127.0.0.1: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多对多的关系不能实现自动创建第三张表需要自己手动创建第三张表,并设置表之间的关系
  • 通过正、反向查询实现自动为其第三张表添加数据
  • 切记当使用正反向查询的时候,注意查询的字段是包含一个值还是一个值,也就是查询表之间的关系>
posted @ 2021-11-06 20:36  RandySun  阅读(72)  评论(0编辑  收藏  举报