zoukankan      html  css  js  c++  java
  • 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操作

    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")
    
    class Son(Base):
        __tablename__ = 'son'
    
        id = Column(Integer,primary_key=True,autoincrement=True)
        name = Column(String(40),unique=True)
        age = Column(Integer)
    
        father_id = Column(Integer,ForeignKey('father.id'))
    
    Base.metadata.create_all(engine)
    
    MySession = sessionmaker(bind=engine)
    session = MySession()
    
    # f = Father(name='ld',age=21)
    # session.add(f)
    # session.commit()
    #
    # s1 = Son(name='ww',age=1,father_id=1)
    # s2 = Son(name='wb',age=0,father_id=1)
    # session.add_all([s1,s2])
    # session.commit()
    #一对多情况下:多(包含外键方)
    
    ret =session.query(Father).filter_by(id=1).first()
    #ret.son 是一个列表,其中多的一方会获得一个列表结果,列表中含有其各个对象
    for i in ret.son:
        print(i.name,i.age)
    
    
    #另一方只会获得一个对象结果
    ret2 = session.query(Son).filter_by(id=1).first()
    print(ret2.father.name)#
    原来代码,不需要看

    只使用外键,需要使用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>
    #直接取值
  • 相关阅读:
    eslint 的 env 配置是干嘛使的?
    cookie httpOnly 打勾
    如何定制 antd 的样式(theme)
    剑指 Offer 66. 构建乘积数组
    剑指 Offer 65. 不用加减乘除做加法
    剑指 Offer 62. 圆圈中最后剩下的数字
    剑指 Offer 61. 扑克牌中的顺子
    剑指 Offer 59
    剑指 Offer 58
    剑指 Offer 58
  • 原文地址:https://www.cnblogs.com/ssyfj/p/8568013.html
Copyright © 2011-2022 走看看