SQLAlchemy多对多关联

创建多对多表结构

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKey

engine = create_engine("mysql+pymysql://root:1@127.0.0.1/tomdb?charset=utf8")
Base = declarative_base()      #生成orm基类,执行SQL语句的类就继承Base

'''1 创建关联表:    第三张表book_m2m_author:用来关联下面的authors和books表'''
# 这张关系表不必使用类创建可以直接使用Table创建,因为这张表创建后不必手动向表中插数据
# 对这张表的维护完全是由ORM自己维护的
# 表中仅有两个字段:book_id关联books表的id,author_id关联authors表的id
# 这张表创建完成后必须要在books表和authors表中指定要到book_m2m_author表查询

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

'''2 创建books表:    用来存储所有作者的名字 '''
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')
    # books通过authors关联Author表,Book通过字段secondary去查第三张表:book_m2m_author
    # backref='books'用来反向查一个作者有多少本书

    def __repr__(self):
        return self.name

'''3 创建authors表    用来存储所有的书 '''
class Author(Base):
    __tablename__ = 'authors'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))

    def __repr__(self):
        return self.name

Base.metadata.create_all(engine)

插入数据

from orm_test import models
from sqlalchemy.orm import sessionmaker

Session_class = sessionmaker(bind=models.engine)
session = Session_class()

'''第一步:向books表和authors表中分别插入三条数据'''
#1、向books表插入三条书名记录
b1 = models.Book(name="python基础教程",pub_date="2014-05-02")
b2 = models.Book(name="从删库到跑路",pub_date="2014-05-02")
b3 = models.Book(name="wireshark网路分析实战",pub_date="2014-05-02")

#2、向authors表插入三条作者记录
a1 = models.Author(name="Tom")
a2 = models.Author(name="Jack")
a3 = models.Author(name="Fly")

#3、这里指定执行上面的创建表命令
session.add_all([b1,b2,b3,a1,a2,a3])
session.commit()

'''第二步:第三张表:book_m2m_author 中创建 作者与书籍的对应关系'''
b1 = session.query(models.Book).filter(models.Book.name=='python基础教程').first()
b2 = session.query(models.Book).filter(models.Book.name=='从删库到跑路').first()
b3 = session.query(models.Book).filter(models.Book.name=='wireshark网路分析实战').first()

a1 = session.query(models.Author).filter(models.Author.name=='Tom').first()
a2 = session.query(models.Author).filter(models.Author.name=='Jack').first()
a3 = session.query(models.Author).filter(models.Author.name=='Fly').first()

b1.authors = [a1,a2]            # 'python基础教程'这本书的作者有:"Tom", "Jack"
a1.books = [b1,b2,b3]           # 作者 "Tom" 出版的书有:python基础教程、从删库到跑路、wireshark网路分析实战
session.commit()

查询数据

from orm_test import models
from sqlalchemy.orm import sessionmaker

Session_class = sessionmaker(bind=models.engine)
session = Session_class()

b1 = session.query(models.Book).filter(models.Book.name=='python基础教程').first()
a1 = session.query(models.Author).filter(models.Author.name=='Tom').first()

#1、正向查找: "python基础教程"  这本书的所有作者
print( b1.authors )       # [Tom, Jack]

#2、反向查找:作者"Tom" 出版的所有书
print( a1.books )        # [python基础教程, 从删库到跑路, wireshark网路分析实战]

修改数据

from orm_test import models
from sqlalchemy.orm import sessionmaker

Session_class = sessionmaker(bind=models.engine)
session = Session_class()

b1 = session.query(models.Book).filter(models.Book.name=='python基础教程').first()
a1 = session.query(models.Author).filter(models.Author.name=='Tom').first()

#1、正向查找: "python基础教程"  这本书的所有作者
print( b1.authors )       # [Tom, Jack]

#2、反向查找:作者"Tom" 出版的所有书
print( a1.books )        # [python基础教程, 从删库到跑路, wireshark网路分析实战]

删除数据

from orm_test import models
from sqlalchemy.orm import sessionmaker

Session_class = sessionmaker(bind=models.engine)
session = Session_class()

b1 = session.query(models.Book).filter(models.Book.name=='python基础教程').first()
a1 = session.query(models.Author).filter(models.Author.name=='Tom').first()

#1、正向删除: 将书籍b1的作者 Tom 删除(只是删除book_m2m_author表中的记录,不会删除authors表中的 'Tom')
print(b1.authors)          # [Tom, Jack]
b1.authors.remove(a1)
print(b1.authors)          # [Jack]
session.commit()

#2、反向删除:
print(a1.books)              # [python基础教程, 从删库到跑路, wireshark网路分析实战]
a1.books.remove(b1)          # [从删库到跑路, wireshark网路分析实战]
print(a1.books)

#3、多对多联级删除: 删除作者时,会把这个作者跟所有书的关联关系数据也自动删除(book_m2m_author中的对应信息)
session.delete(a1)
session.commit()


发表评论