• 西游之路——python全栈——ORM之SQLAlchemy(3)外键与relationship的关系


     

    relationship是为了简化联合查询join等,创建的两个表之间的虚拟关系,这种关系与标的结构时无关的。他与外键十分相似,确实,他必须在外键的基础上才允许使用

    不然会报错:

    sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Father.son - there are no foreign keys linking these tables.  Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression

    详细的relationship可以点击这里进行查看

    relationship的使用:

    使两个表之间产生管理,类似于合成一张表,可以直接取出关联的表,进行获取数据,而不需要join操作

     1 import sqlalchemy
     2 from sqlalchemy import create_engine
     3 from sqlalchemy import Column,String,Integer,ForeignKey
     4 from sqlalchemy.orm import sessionmaker,relationship
     5 from sqlalchemy.ext.declarative import declarative_base
     6 
     7 engine = create_engine("mysql+pymysql://root:root@127.0.0.1/t1")
     8 
     9 Base = declarative_base()
    10 
    11 class Father(Base):
    12     __tablename__ = "father"
    13 
    14     id = Column(Integer,primary_key=True,autoincrement=True)
    15     name = Column(String(40),unique=True)
    16     age = Column(Integer)
    17     son = relationship('Son',backref="father")
    18 
    19 class Son(Base):
    20     __tablename__ = 'son'
    21 
    22     id = Column(Integer,primary_key=True,autoincrement=True)
    23     name = Column(String(40),unique=True)
    24     age = Column(Integer)
    25 
    26     father_id = Column(Integer,ForeignKey('father.id'))
    27 
    28 Base.metadata.create_all(engine)
    29 
    30 MySession = sessionmaker(bind=engine)
    31 session = MySession()
    32 
    33 # f = Father(name='ld',age=21)
    34 # session.add(f)
    35 # session.commit()
    36 #
    37 # s1 = Son(name='ww',age=1,father_id=1)
    38 # s2 = Son(name='wb',age=0,father_id=1)
    39 # session.add_all([s1,s2])
    40 # session.commit()
    41 #一对多情况下:多(包含外键方)
    42 
    43 ret =session.query(Father).filter_by(id=1).first()
    44 #ret.son 是一个列表,其中多的一方会获得一个列表结果,列表中含有其各个对象
    45 for i in ret.son:
    46     print(i.name,i.age)
    47 
    48 
    49 #另一方只会获得一个对象结果
    50 ret2 = session.query(Son).filter_by(id=1).first()
    51 print(ret2.father.name)#
    52 
    53 原来代码,不需要看
    原来代码,不需要看

    只使用外键,需要使用join才可以取出数据

    #上面不存在relationship
    ret = session.query(Father.name.label('kkk'),Son.name.label("ppp")).join(Son).all()#使用Join才可以获取对方数据 print(ret)#是一个列表,列表中存在所要获取的数据(以元组存在)

    在外键基础上使用relationship:可以直接通过属性操作获取数据

    #使用了relationship
    ret = session.query(Father).filter_by(id=1).first() print(ret.son)#是一个对象列表,其中包含了所有查询数据

     全部代码:

    其中son = relationship('Son',backref="Father")

    相当于在Son中加入father = relationship('Father')在Father中加入son = relationship('Son')

    复制代码
    import sqlalchemy
    from sqlalchemy import create_engine
    from sqlalchemy import Column,String,Integer,ForeignKey
    from sqlalchemy.orm import sessionmaker,relationship
    from sqlalchemy.ext.declarative import declarative_base
    
    engine = create_engine("mysql+pymysql://root:root@127.0.0.1/t1")
    
    Base = declarative_base()
    
    class Father(Base):
        __tablename__ = "father"
    
        id = Column(Integer,primary_key=True,autoincrement=True)
        name = Column(String(40),unique=True)
        age = Column(Integer)
        son = relationship('Son',backref="Father")
        #son = relationship('Son')
    
    class Son(Base):
        __tablename__ = 'son'
    
        id = Column(Integer,primary_key=True,autoincrement=True)
        name = Column(String(40),unique=True)
        age = Column(Integer)
        #father = relationship('Father')
    
        father_id = Column(Integer,ForeignKey('father.id'))
    
    Base.metadata.create_all(engine)
    
    MySession = sessionmaker(bind=engine)
    session = MySession()
    
    ret = session.query(Father).filter_by(id=1).first()
    print(ret.son) #多个结果[<__main__.Son object at 0x0000000003F192B0>, <__main__.Son object at 0x0000000003F19320>]
    #需要循环取值
    
    ret = session.query(Son).filter_by(id=1).first()
    print(ret.father)#一个结果<__main__.Father object at 0x0000000003F196D8>
    #直接取值
    复制代码
  • 相关阅读:
    WebGL——osg框架学习一
    webgl绘制粗线段
    ThreeJS实现波纹粒子效果
    WebGL——水波纹特效
    WebGL之shaderToy初使用
    有效提升职场竞争力
    Windows结构化异常处理浅析
    一起学习Boost标准库--Boost.StringAlgorithms库
    科学计算工具-Numpy初探
    进程动态拦截注入API HOOK
  • 原文地址:https://www.cnblogs.com/Lujun1028/p/9961092.html
Copyright © 2020-2023  润新知