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:[email protected]/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:[email protected]/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> #直接取值