SQLAlchemy-對象關系教程ORM-連接,子查詢


對象關系教程ORM-連接

一:內連接

方法一:

for u, a in session.query(User, Address).\
                    filter(User.id==Address.user_id).\
                     filter(Address.email_address=='jack@google.com').\
                     all():
     print(u)
     print(a)

方法二:

session.query(User).join(Address).\
        filter(Address.email_address=='jack@google.com').\
        all()

  Query.join()知道如何加入之間 User Address因為他們之間只有一個外鍵

二:左連接

  

query.outerjoin(User.addresses)# LEFT OUTER JOIN

三:使用別名

  跨多個表查詢時,如果相同的表需要不止一次引用,表的SQL通常需要與另一個名稱別名,這樣它就可以被區分與其他表的出現。 Query支持這個最顯式地使用 aliased構造。下面我們加入的 Address實體兩次,來定位用戶在同一時間有兩個不同的電子郵件地址

>>> from sqlalchemy.orm import aliased
>>> adalias1 = aliased(Address)
>>> adalias2 = aliased(Address)
SQL>>> for username, email1, email2 in \
...     session.query(User.name, adalias1.email_address, adalias2.email_address).\
...     join(adalias1, User.addresses).\
...     join(adalias2, User.addresses).\
...     filter(adalias1.email_address=='jack@google.com').\
...     filter(adalias2.email_address=='j25@yahoo.com'):
...     print(username, email1, email2)

四:使用子查詢

 Query適用於生成報表,可以用作子查詢。假設我們想負載 User對象數的多少 Address每個用戶都有記錄。生成SQL的最好方法是獲取地址分組的用戶id,並加入到父。在本例中,我們使用一個左外連接,這樣我們拿回行對於那些用戶沒有任何地址

使用 Query,我們建立一個這樣的聲明由內而外。 statement訪問器返回一個代表聲明由一個特定的SQL表達式 Query——這是一個實例 select()構造,中描述SQL表達式語言教程:

 func關鍵字生成SQL函數, subquery()方法 Query生成一個SQL表達式構造代表一個SELECT語句嵌入一個別名(實際上是縮寫query.statement.alias()).

 

一旦我們有聲明,它像一個 Table構造,如我們創建的 users在本教程的開始。聲明可通過一個屬性的列 c:

SELECT users.*, adr_count.address_count FROM users LEFT OUTER JOIN
    (SELECT user_id, count(*) AS address_count
        FROM addresses GROUP BY user_id) AS adr_count
    ON users.id=adr_count.user_id



from sqlalchemy.sql import func
>>> stmt = session.query(Address.user_id, func.count('*').\
...         label('address_count')).\
...         group_by(Address.user_id).subquery()


>>> from sqlalchemy.sql import func
>>> stmt = session.query(Address.user_id, func.count('*').\
...         label('address_count')).\
...         group_by(Address.user_id).subquery()

>>> for u, count in session.query(User, stmt.c.address_count).\
...     outerjoin(stmt, User.id==stmt.c.user_id).order_by(User.id):
...     print(u, count)


五:從子查詢選擇實體

>>> stmt = session.query(Address).\
...                 filter(Address.email_address != 'j25@yahoo.com').\
...                 subquery()
>>> adalias = aliased(Address, stmt)
>>> for user, address in session.query(User, adalias).\
...         join(adalias, User.addresses):
...     print(user)
...     print(address)
 
        

六:使用存在

 
        

在SQL中存在關鍵字是一個布爾操作符,返回True,如果給定的表達式包含任何行。也許在很多場景中使用的連接,也用於定位行,沒有一個相關的表中相應的行。

 
        

存在一個顯式構造,它看起來像這樣:

 
        

 

>>> from sqlalchemy.sql import exists
>>> stmt = exists().where(Address.user_id==User.id)
SQL>>> for name, in session.query(User.name).filter(stmt):
...     print(name)

 

  Query自動功能使多個運算符使用存在。以上,聲明可以表達的 User.addresses使用的關系 any():

>>> for name, in session.query(User.name).\
...         filter(User.addresses.any()):
...     print(name)

has()運營商一樣嗎 any()多對一的關系(注意 ~運營商,這意味着“不”):

>>>session.query(Address).\
...filter(~Address.user.has(User.name=='jack')).all()[]

七:常見的關系操作符

這是所有的運營商建立關系,每一個與它的API文檔包括使用詳情和行為:

  • __eq__()(多對一的“=”比較):

    query.filter(Address.user==someuser)
  • __ne__()(多對一的“不等於”比較):

    query.filter(Address.user!=someuser)
  • 為空(多對一的比較,還使用嗎 __eq__()):

    query.filter(Address.user==None)
  • contains()(用於一對多收藏):

    query.filter(User.addresses.contains(someaddress))
  • any()(用於收藏):

    query.filter(User.addresses.any(Address.email_address=='bar'))# also takes keyword arguments:query.filter(User.addresses.any(email_address='bar'))
  • has()(用於標量引用):

    query.filter(Address.user.has(name='ed'))
  • Query.with_parent()(用於任何關系):

    session.query(Address).with_parent(someuser,'addresses')

 

刪除

session.delete(jack)

session.query(User).filter_by(name='jack').count()

級聯刪除

 class User(Base):
...     __tablename__ = 'users'
...
...     id = Column(Integer, primary_key=True)
...     name = Column(String)
...     fullname = Column(String)
...     password = Column(String)
...
...     addresses = relationship("Address", back_populates='user',
...                     cascade="all, delete, delete-orphan")
...
...     def __repr__(self):
...        return "<User(name='%s', fullname='%s', password='%s')>" % (
...                                self.name, self.fullname, self.password)

 


免責聲明!

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



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