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)
最新文章
- Socket服务端和客户端(C++,CodeBlocks+GCC编译)
- java21
- OpenCV图像金字塔:高斯金字塔、拉普拉斯金字塔与图片尺寸缩放
- POJ 1650 Integer Approximation
- 【IOS笔记】About Events in iOS
- Json文件放入Assets文件,读取解析并且放入listview中显示。
- ionic build --release android
- UML基本表示法(转载)
- 《C++ Primer》读书笔记—第一章 开始
- 百词斩APP分析
- SpringBoot实现多环境配置
- Windows服务器
- Java中String直接赋字符串和new String的区别(面试常考)
- 【WPF】图片按钮的单击与双击事件
- Mysql 函数使用记录(三)——UNIX_TIMESTAMP() 、UNIX_TIMESTAMP(date)
- C#语言,求成绩平均数。
- JAVA优化技巧分享 让游戏更加的流畅
- perl6正则 6: 大小写/空白/匹配所有符合
- php--session垃圾回收机制
- 【Python之路】第二十一篇--Memcached、Redis
热门文章
- HIGH-SPEED PACKET PROCESSING USING RECONFIGURABLE COMPUTING
- bzoj 4332:JSOI2012 分零食
- Java入门:基础算法之检查奇偶性
- Nginx反向代理websocket配置实例(官网)
- mongodb_修改器($inc/$set/$unset/$push/$pop/upsert)
- [JSOI2007]字符加密Cipher
- Django 2.0.1 官方文档翻译: 高级教程:如何编写可重用的app (page 13)
- Nginx+tomcat 负载均衡
- js封装Cookie操作
- noip2012 P1081 开车旅行