对象关系教程ORM-链接python
方法一:sql
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)
方法二:express
session.query(User).join(Address).\ filter(Address.email_address=='jack@google.com').\ all()
Query.join()
知道如何加入之间 User
和 Address
由于他们之间只有一个外键session
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,并加入到父。在本例中,咱们使用一个左外链接,这样咱们拿回行对于那些用户没有任何地址google
使用 Query
,咱们创建一个这样的声明由内而外。的 statement
访问器返回一个表明声明由一个特定的SQL表达式 Query
——这是一个实例 select()
构造,中描述SQL表达式语言教程:spa
的 func
关键字生成SQL函数, subquery()
方法 Query
生成一个SQL表达式构造表明一个SELECT语句嵌入一个别名(其实是缩写query.statement.alias()
).code
一旦咱们有声明,它像一个 Table
构造,如咱们建立的 users
在本教程的开始。声明可经过一个属性的列 c
:orm
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)