专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

sqlalchemy在python中的使用(表之间的关系)四

本章节介绍SQLAlchemy的表关系,主要分为以下几种

  • 1、一对多关系
  • 2、一对一的关系
  • 3、多对多的关系

一、一对多的关系

在多表关联中,常见的是一对多的关系,但是有时候我们也会听到多对一的关系,其实他们仅仅是站在不同的角度上来看的表关系,(本案例中采用用户与文章来说明)

  • 1、一个用户可以写多篇文章(用户对文章是一对多的关系)
  • 2、文章只能有一个用户(多对一的关系)

具体的代码实现

  • 1、基本的导包
    from sqlalchemy import Column, Integer, String, DateTime, Boolean, TIMESTAMP, func
    from sqlalchemy.orm import relationship

    from sqlalchemy_demo.connect import Base
    from sqlalchemy import ForeignKey

  • 2、创建一个用户表的module
    class UserModule(Base):
        """
        创建一个用户的数据模型
        """
        __tablename__ = 'user'

        id = Column(Integer, primary_key=True, autoincrement=True, comment='用户id')
        user_name = Column(String(30), nullable=False, unique=True, comment='用户名')
        password = Column(String(64), nullable=False, comment='用户密码')

        def __repr__(self):
            return 'User({},{})'.format(self.user_name, self.password)

  • 3、创建一个文章表的module
    class ArticleList(Base):
        """
        文章列表页面
        """
        __tablename__ = 'article_list'

        id = Column(Integer, primary_key=True, autoincrement=True, comment='文章id')
        title = Column(String(100), nullable=False, default='', comment='文章标题')

        def __repr__(self):
            return 'ArticleList({})'.format(self.title)

  • 4、在子表中(相对来说是多的那端)使用ForeignKey关联到父表(注意数据类型要一致)
    class ArticleList(Base):
        """
        文章列表页面
        """
        ...
        # 外键关联(关联的key的类型要和定义的类型一致)
        user_id = Column(Integer, ForeignKey(UserModule.id), comment='文章作者')
        ...

  • 5、在父表中使用relationship方法来引用子表的数据(就是说关联了,可以通过父表查询到子表的数据[本案例中:根据用户查询到文字])
    class UserModule(Base):
        """
        创建一个用户的数据模型
        """
        ...
        article_list = relationship('ArticleList')
        ...

  • 6、上面仅仅是建立的父表可以访问到子表的数据,如果要子表也要访问到父表的数据就在relationship中多加一个参数backref
    class UserModule(Base):
        """
        创建一个用户的数据模型
        """
        ...
        article_list = relationship('ArticleList', backref='user')
        ...

  • 7、子表访问父表还有另外一种方式,使用back_populates(和上面方法任选一个)
    • 在父表中
        class UserModule(Base):
        """
        创建一个用户的数据模型
        """
        ...

        article_list = relationship('ArticleList', back_populates='user')

 *  在子表中
        class ArticleList(Base):
        """
        文章列表页面
        """
        __tablename__ = 'article_list'
        ...
        # 外键关联
        user_id = Column(Integer, ForeignKey(UserModule.id), comment='文章作者')
        # 通过关联起来,这样在文章列表页面可以获取用户表的信息
        user = relationship(UserModule, back_populates='article_list')

  • 8、测试一(父表查询到子表数据)
    ...
    def query_user():
        rows = dbSession.query(UserModule).first() # 获取到父表第一条数据
        print(rows.article_list) # 获取
    ...

  • 9、测试二(子表查询到父表数据)
    ...
    def query_user():
        rows = dbSession.query(ArticleList).first() # 获取到文章的第一条数据
        print(rows.user) # 获取文章的作者
    ...

二、一对一的关系

常见的一对一的关系,一般是表的扩展,比如用户表及用户扩展表,文章及文章详情这样的,操作方式也很简单,只要在一对多的基础上加上uselist=False就可以

  • 1、用户模型
    class UserModule(Base):
        """
        创建一个用户的数据模型
        """
        __tablename__ = 'user'

        id = Column(Integer, primary_key=True, autoincrement=True, comment='用户id')
        user_name = Column(String(30), nullable=False, unique=True, comment='用户名')
        password = Column(String(64), nullable=False, comment='用户密码')
         # 一对多关系中关联文章列表的
        article_list = relationship('ArticleList', backref='user')

        def __repr__(self):
            return 'User({},{})'.format(self.user_name, self.password)

  • 2、用户扩展表
    class UserExtendModule(Base):
        """
        用户扩展的模型
        """
        __tablename__ = 'user_extend'
        id = Column(Integer, primary_key=True, autoincrement=True, comment='id')
        gender = Column(String(3), nullable=True, comment='性别')
        birthday = Column(DateTime, nullable=True, comment='出生年月')
        position = Column(String(20), nullable=True, comment='职位')
         # 外键关联到用户表
        user_id = Column(Integer, ForeignKey(UserModule.id), unique=True, comment='关联父id')
         # 创建关系,用户扩展表与用户表建立关系
        user = relationship('UserModule', backref='user_detail', uselist=False, cascade='all')

        def __repr__(self):
            return 'user extend({},{}, {})'.format(self.gender, self.birthday, self.position)

  • 3、测试代码
    • 1.用户表查找到用户扩展表
        def query_user():
            rows = dbSession.query(UserModule).first()
            print(dir(rows))
            print(rows.user_detail)

 *  2.反向查找(用户扩展表查找到用户)
        def query_user():
            rows = dbSession.query(UserExtendModule).first()
            print(dir(rows))
            print(rows.user)

三、关于relationship(module, backref='', uselist=True, cascade='')的参数介绍

  • 1、module关联的数据模型(如果是在当前的上面可以不加引号)
  • 2、backref在关联的module中添加属性
  • 3、uselist默认是True表示一对多的关系,如果是一对一的关系就要设置False
  • 4、cascade自动关系处理(比如一对一中删除父表数据,子表数据是否删除)

四、关于cascade几个属性的介绍

  • 1、all:所有操作都会自动处理到关联对象上
  • 2、save-update:关联对象自动添加到会话上
  • 3、delete:关联对象自动从会话中删除
  • 4、delete-orphan:属性中去掉关联对象,则会话中会自动删除关联对象
  • 5、merge:session.merge()时会处理关联对象
  • 6、refresh-expire: session.expire()时会处理关联对象
  • 7、expunge:session.expunge()时会处理关联对象

五、多对多的关系

mysql中处理多对多的关系的时候,我们都是创建一个第三张表,使用上面的一对多的技术,本案例使用(文章与tag来描素多对多的关系)

  • 1、文章表
    class ArticleList(Base):
        """
        文章列表页面
        """
        __tablename__ = 'article_list'

        id = Column(Integer, primary_key=True, autoincrement=True, comment='文章id')
        title = Column(String(100), nullable=False, default='', comment='文章标题')
        # 外键关联
        user_id = Column(Integer, ForeignKey(UserModule.id), comment='文章作者')

        def __repr__(self):
            return 'ArticleList({})'.format(self.title)

  • 2、创建一个tag
    class TagModule(Base):
        """
        文章Tag模型
        """
        __tablename__ = 'tag'
        id = Column(Integer, primary_key=True, autoincrement=True, comment='主键')
        name = Column(String(30), nullable=False, default='', comment='tag名字')

        def __repr__(self):
            return 'TagModule({},{})'.format(self.id, self.name)

  • 3、导包Table
    from sqlalchemy import ForeignKey, Table

  • 4、创建中间表
    article_tag = Table(
        'article_tag',
        Base.metadata,
        Column('article_id', Integer, ForeignKey(ArticleList.id), primary_key=True, comment='文章id'),
        Column('tag_id', Integer, ForeignKey(TagModule.id), primary_key=True, comment='tag表id')
    )

  • 5、在TagModule数据模型中新增关联关系
    class TagModule(Base):
        """
        文章Tag模型
        """
        # secondary指向中间表,是表名
        ...
        tag_article = relationship(ArticleList, backref='tags', secondary='article_tag')
        ...

  • 6、手动插入数据
  • 7、测试
    • 1.根据文章查找到tag
        def query_user():
            rows = dbSession.query(ArticleList).first()
            print(dir(rows))
            print(rows.tags)

 *  2.从`tag`表中查找文章
        def query_user():
            rows = dbSession.query(TagModule).first()
            print(dir(rows))
            print(rows.tag_article)

未经允许不得转载:搜云库技术团队 » sqlalchemy在python中的使用(表之间的关系)四

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们