zoukankan      html  css  js  c++  java
  • sqlalchemy 多对多关系

    一、前言

      多对多的关系是一张表可以关联多张表。 

      现在来设计一个能描述“图书”与“作者”的关系的表结构,需求是

    1. 一本书可以有好几个作者一起出版
    2. 一个作者可以写好几本书

    二、表结构和数据

      

    book_m2m_author表由author表和book表生成

    三、事例

    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
    
    # 如果插入数据有中文,需要指定 charset=utf8
    engine = create_engine("mysql+pymysql://bigberg:111111@172.16.200.49:3306/study?charset=utf8",
                           encoding='utf-8')
    
    Base = declarative_base()  # 创建orm基类
    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")))
    
    
    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
    
    # 创建表
    Base.metadata.create_all(engine)
    创建表
    mysql> desc authors;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type        | Null | Key | Default | Extra          |
    +-------+-------------+------+-----+---------+----------------+
    | id    | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(32) | YES  |     | NULL    |                |
    +-------+-------------+------+-----+---------+----------------+
    2 rows in set (0.00 sec)
    
    mysql> desc books;
    +----------+-------------+------+-----+---------+----------------+
    | Field    | Type        | Null | Key | Default | Extra          |
    +----------+-------------+------+-----+---------+----------------+
    | id       | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name     | varchar(64) | YES  |     | NULL    |                |
    | pub_date | date        | YES  |     | NULL    |                |
    +----------+-------------+------+-----+---------+----------------+
    3 rows in set (0.00 sec)
    
    mysql> desc book_m2m_author;
    +------------+---------+------+-----+---------+----------------+
    | Field      | Type    | Null | Key | Default | Extra          |
    +------------+---------+------+-----+---------+----------------+
    | id         | int(11) | NO   | PRI | NULL    | auto_increment |
    | books_id   | int(11) | YES  | MUL | NULL    |                |
    | authors_id | int(11) | YES  | MUL | NULL    |                |
    +------------+---------+------+-----+---------+----------------+
    3 rows in set (0.00 sec)
    表结构

    四、插入数据

    # -*- coding: UTF-8 -*-
    import m2m_orm
    from m2m_orm import Author
    from m2m_orm import Book
    from sqlalchemy.orm import sessionmaker
    
    # 创建session会话
    Session_class = sessionmaker(bind=m2m_orm.engine)
    # 生成session实例
    session = Session_class()
    
    b1 = Book(name="python学习", pub_date="2018-01-01")
    b2 = Book(name="linux学习", pub_date="2018-02-01")
    b3 = Book(name="mysql学习", pub_date="2018-03-01")
    
    a1 = Author(name="Jack")
    a2 = Author(name="Jerru")
    a3 = Author(name="Marry")
    
    b1.authors = [a1,a2]
    b2.authors = [a2,a3]
    b3.authors = [a1,a2,a3]
    
    session.add_all([b1,b2,b3,a1,a2,a3])
    session.commit()
    插入数据
    mysql> select * from books;
    +----+--------------+------------+
    | id | name         | pub_date   |
    +----+--------------+------------+
    |  1 | python学习   | 2018-01-01 |
    |  2 | mysql学习    | 2018-03-01 |
    |  3 | linux学习    | 2018-02-01 |
    +----+--------------+------------+
    3 rows in set (0.00 sec)
    
    mysql> select * from authors;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | Jack  |
    |  2 | Marry |
    |  3 | Jerru |
    +----+-------+
    3 rows in set (0.00 sec)
    
    mysql> select * from book_m2m_author;
    +----+----------+------------+
    | id | books_id | authors_id |
    +----+----------+------------+
    |  1 |        2 |          1 |
    |  2 |        2 |          3 |
    |  3 |        2 |          2 |
    |  4 |        3 |          3 |
    |  5 |        3 |          2 |
    |  6 |        1 |          1 |
    |  7 |        1 |          3 |
    +----+----------+------------+
    7 rows in set (0.00 sec)
    数据内容

    五、查询数据

    # -*- coding: UTF-8 -*-
    
    import m2m_orm
    from m2m_orm import Author
    from m2m_orm import Book
    from sqlalchemy.orm import sessionmaker
    
    # 创建session会话
    Session_class = sessionmaker(bind=m2m_orm.engine)
    # 生成session实例
    session = Session_class()
    
    print("通过作者表查关联书".center(30, '-'))
    author_obj = session.query(Author).filter(Author.name=='Jack').first()
    print(author_obj.name, author_obj.books, author_obj.books[0].pub_date)
    
    print("通过书表查关联作者".center(30, '-'))
    book_obj = session.query(Book).filter(Book.id==2).first()
    print(book_obj.name, book_obj.authors)
    
    
    # 输出
    ----------通过作者表查关联书-----------
    Jack [python学习, mysql学习] 2018-01-01
    ----------通过书表查关联作者-----------
    mysql学习 [Jack, Marry, Jerru]
    查询数据

    六、删除数据

      删除数据时不用管boo_m2m_authors , sqlalchemy会自动帮你把对应的数据删除

      6.1 通过书删除作者

    author_obj = session.query(Author).filter(Author.name=='Jack').first()
    book_obj = session.query(Book).filter(Book.id==2).first()
    print(author_obj.name)
    print(book_obj.authors)
    book_obj.authors.remove(author_obj)
    print(book_obj.authors)
    session.commit()
    
    # 输出
    Jack
    [Jack, Marry, Jerru]
    [Marry, Jerru]
    

      6.2 直接删除作者

    author_obj = session.query(Author).filter(Author.name=='Jack').first()
    print(author_obj.name)
    session.delete(author_obj)
    session.commit()
    

      

    mysql> select * from authors;
    +----+-------+
    | id | name  |
    +----+-------+
    |  2 | Marry |
    |  3 | Jerru |
    +----+-------+
    2 rows in set (0.00 sec)
    
    mysql> select * from books;
    +----+--------------+------------+
    | id | name         | pub_date   |
    +----+--------------+------------+
    |  1 | python学习   | 2018-01-01 |
    |  2 | mysql学习    | 2018-03-01 |
    |  3 | linux学习    | 2018-02-01 |
    +----+--------------+------------+
    3 rows in set (0.00 sec)
    
    mysql> select * from book_m2m_author;
    +----+----------+------------+
    | id | books_id | authors_id |
    +----+----------+------------+
    |  2 |        2 |          3 |
    |  3 |        2 |          2 |
    |  4 |        3 |          3 |
    |  5 |        3 |          2 |
    |  7 |        1 |          3 |
    +----+----------+------------+
    5 rows in set (0.00 sec)
    
    # 这是直接将作者从表中删除了
    

      

  • 相关阅读:
    第三章 运算符与表达式
    python 第二章 对象与类型
    线段树区间染色+注意事项
    ACM-ICPC北京赛区2018重现赛 A题
    删除元组
    修改元组
    访问元组
    Python 元组
    Python List sort()方法
    hdu4501——小明系列故事——买年货(多维背包)
  • 原文地址:https://www.cnblogs.com/bigberg/p/8330849.html
Copyright © 2011-2022 走看看