1. 程式人生 > >西遊之路——python全棧——ORM之SQLAlchemy(3)外來鍵與relationship的關係

西遊之路——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:[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>
#直接取值
複製程式碼

 

目錄

 

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>
#直接取值
複製程式碼