zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    SQL语句编写
    触发器
    plot函数中的type中的参数
    【转】R中read.table详解
    7月18日R笔记
    RMySQL在windows下的安装方法
    WinXP下面实现JAVA对R调用 (rJava包设置)
    用R进行文档层次聚类完整实例(tm包)
    R学习之R层次聚类方法(tm包)
    R对term进行层次聚类完整实例(tm包)
  • 原文地址:https://www.cnblogs.com/lixiang1013/p/7397878.html
Copyright © 2011-2022 走看看