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>
#直接取值

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM