zoukankan      html  css  js  c++  java
  • SQLAlchemy-对象关系教程ORM-一对多(外键),一对一,多对多

    一:一对多

      表示一对多的关系时,在子表类中通过 foreign key (外键)引用父表类,然后,在父表类中通过 relationship() 方法来引用子表的类。

    一对多的关系中建立双向的关系,这样的话在对方看来这就是一个多对一的关系,在子表类中附加一个 relationship() 方法,并且在双方的 relationship() 方法中使用 relationship.back_populates 方法参数。这样的话子表将会在多对一的关系中获得父表的属性,或者,可以在单一的 relationship() 方法中使用 backref 参数来代替 back_populates 参数。

    class Parent(Base):
        __tablename__ = 'parent'
        id = Column(Integer, primary_key=True)
        children = relationship("Child", back_populates="parent")
    
    class Child(Base):
        __tablename__ = 'child'
        id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('parent.id'))
        parent = relationship("Parent", back_populates="children")
        # 子表类中附加一个 relationship() 方法
        # 并且在(父)子表类的 relationship() 方法中使用 relationship.back_populates 参数

      注意:Child.parent是指一个Parent实例,另一方面,Parent.children 是指的一个Child实例列表。

      

    # -*- coding:utf-8 -*-
    __author__ = 'shisanjun'
    import sqlalchemy
    from sqlalchemy import Column,Integer,String,ForeignKey
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker,relationship
    
    #创建连接
    engine=sqlalchemy.create_engine("mysql+pymysql://admin:admin@192.168.0.121/test2?charset=utf8",echo=True)
    
    #声明ORM映射基类
    BASE=declarative_base()
    
    class User(BASE):
        __tablename__="users" #指定表名
        id=Column(Integer,primary_key=True) #建立主键
        name=Column(String(32))
        fullname=Column(String(32))
        password=Column(String(32))
    
        def __repr__(self): #返回对象时打印显示
            return "name:%s full name:%s password:%s" %(self.name,self.fullname,self.password)
    
    class Address(BASE):
         __tablename__ = 'addresses'
         id = Column(Integer, primary_key=True)
         email_address = Column(String, nullable=False)
         user_id = Column(Integer, ForeignKey('users.id'))
    
         user = relationship("User", back_populates="addresses")
    
         def __repr__(self):
             return "<Address(email_address='%s')>" % self.email_address
    
    BASE.metadata.create_all(engine)
    
    Session=sessionmaker(bind=engine)
    #实例化会话类
    session=Session()
    
    jack=User(name='jack',fullname='Jack Bean',password='gjffdd')
    jack.addresses = [
        Address(email_address='jack@google.com'),
        Address(email_address='j25@yahoo.com')]
    
    session.add(jack)
    session.commit()
    
    jack = session.query(User).filter_by(name='jack').one()
    print(jack.addresses)

    二:一对一

       一对一是两张表之间本质上的双向关系。 要做到这一点,只需要在一对多关系基础上的父表中使用 uselist 参数来表示。

      

    class Parent(Base):
        __tablename__ = 'parent'
        id = Column(Integer, primary_key=True)
        child = relationship("Child", uselist=False, back_populates="parent")
    
    class Child(Base):
        __tablename__ = 'child'
        id = Column(Integer, primary_key=True)
        parent_id = Column(Integer, ForeignKey('parent.id'))
        parent = relationship("Parent", back_populates="child")

    三:多对多

      多对多关系会在两个类之间增加一个关联的表。 

      这个关联的表在 relationship() 方法中通过 secondary 参数来表示

      通常的,这个表会通过 MetaData 对象来与声明基类关联

       所以这个 ForeignKey 指令会使用链接来定位到远程的表

    双向关系中,两个表类都会包含这个集合。 

    指定使用 relationship.back_populates 参数,并且为每一个 relationship() 方法指定共用的关联表

    当在父表类的 relationship() 方法中使用 backref参数代替 relationship.back_populates 时,backref 会自动的为子表类加载同样的secondary 参数

    association_table = Table('association', Base.metadata,
        Column('left_id', Integer, ForeignKey('left.id')),
        Column('right_id', Integer, ForeignKey('right.id'))
    )
    
    class Parent(Base):
        __tablename__ = 'left'
        id = Column(Integer, primary_key=True)
        children = relationship("Child",
                        secondary=association_table,
                        backref="parents")
    
    class Child(Base):
        __tablename__ = 'right'
        id = Column(Integer, primary_key=True)
  • 相关阅读:
    03-hibernate注解-关系映射级别注解-一对一
    02-hibernate注解-属性级别注解
    linux下使用vim替换文件中的^M换行符
    maven项目中找不到Maven Dependencies解决办法
    软件设计师教程(第5版)- 前言和目录
    wireshark抓包分析工具的使用
    Tcpdump抓包工具的使用
    如何使用maven优雅地管理项目版本号
    Linux系统盘扩容-物理机非虚拟机
    eclipse下安装windowbuilder(一定要看)
  • 原文地址:https://www.cnblogs.com/lixiang1013/p/7392109.html
Copyright © 2011-2022 走看看