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)
SQLAlchemy-对象关系教程ORM-连接,子查询的更多相关文章
- Object Relational Tutorial 对象关系教程
The SQLAlchemy Object Relational Mapper presents a method of associating user-defined Python classes ...
- 对象关系映射ORM
对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从效 ...
- Android数据库框架——ORMLite轻量级的对象关系映射(ORM)Java包
Android数据库框架--ORMLite轻量级的对象关系映射(ORM)Java包 事实上,我想写数据库的念头已经很久了,在之前写了一个答题系统的小项目那只是初步的带了一下数据库,数据库是比较强大的, ...
- Python 3 对象关系映射(ORM)
ORM 对象关系映射 Object Relational Mapping 表 ---> 类 字段 ---> 属性 记录 ---> 对象 # mysql_client.py impor ...
- Django 源码小剖: Django 对象关系映射(ORM)
引 从前面已经知道, 一个 request 的到来和一个对应 response 的返回的流程, 数据处理和数据库离不开. 我们也经常在 views.py 的函数定义中与数据库打交道. django O ...
- C#构造方法(函数) C#方法重载 C#字段和属性 MUI实现上拉加载和下拉刷新 SVN常用功能介绍(二) SVN常用功能介绍(一) ASP.NET常用内置对象之——Server sql server——子查询 C#接口 字符串的本质 AJAX原生JavaScript写法
C#构造方法(函数) 一.概括 1.通常创建一个对象的方法如图: 通过 Student tom = new Student(); 创建tom对象,这种创建实例的形式被称为构造方法. 简述:用来初 ...
- Oracle 自连接 / 外连接 / 子查询
--连接查询的三种格式 select ename, deptno,dname from emp natural join dept; select ename, deptno,dname from e ...
- sql 内连接 子查询 合并查询
-- 内连接:-- 显示员工姓名.工资和公司所在地 select e.ename, e.sal, d.dname from emp e,dept d; -- 笛卡尔积 select e.ename, ...
- mysql数据库中的多表查询(内连接,外连接,子查询)
用两个表(a_table.b_table),关联字段a_table.a_id和b_table.b_id来演示一下MySQL的内连接.外连接( 左(外)连接.右(外)连接.全(外)连接). MySQL版 ...
- 通过java反射实现简单的关于MongoDB的对象关系映射(ORM).
通过阅读MongoDB 3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMo ...
随机推荐
- 【bzoj1833】 ZJOI2010—count 数字计数
http://www.lydsy.com/JudgeOnline/problem.php?id=1833 (题目链接) 题意 求在${[a,b]}$范围内整数中,每个数码出现的次数. Solution ...
- springboot项目添加jsp支持
一.创建springboot项目 使用 http://start.spring.io/ 快速创建一个springboot项目下载并导入 二.添加依赖 在pom.xml中添加支持jsp的依赖如下: &l ...
- Eclipse Oxygen(4.7.0)安装插件Eclipse Class Decompiler反编译JAR文件
引用自官方内容 Eclipse Class Decompiler是一款Eclipse插件,整合了多种反编译器,和Eclipse Class Viewer无缝集成,能够很方便的使用插件查看类库源码,进行 ...
- fcntl文件锁操作
文件锁经常应用于两个方面:1.一是锁定文件中的临界数据,比如并发投票时文件记录的投票数2.二是利用具有互斥性质的写锁,实现进程的并发控制. /*使用文件锁*/<F5>#include &l ...
- 130. Surrounded Regions(M)
130.Add to List 130. Surrounded Regions Given a 2D board containing 'X' and 'O' (the letter O), capt ...
- 【题解】Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths Codeforces 741D DSU on Tree
Prelude 很好的模板题. 传送到Codeforces:(* ̄3 ̄)╭ Solution 首先要会DSU on Tree,不会的看这里:(❤ ω ❤). 众所周知DSU on Tree是可以用来处 ...
- Xpath语法与lxml库的用法
BeautifulSoup 已经是非常强大的库了,不过还有一些比较流行的解析库,例如 lxml,使用的是 Xpath 语法,同样是效率比较高的解析方法. 1.安装 pip install lxml 2 ...
- java8 新特性 Stream
1. Stream初体验 我们先来看看Java里面是怎么定义Stream的: A sequence of elements supporting sequential and parallel agg ...
- vue 打印页面部分区域
1. vue项目打印页面部分区域 2. 原生js实现页面局部打印功能 3. vue项目中将table组件导出Excel表格以及打印页面内容
- Nginx模块Lua-Nginx-Module学习笔记(二)Lua指令详解(Directives)
源码地址:https://github.com/Tinywan/Lua-Nginx-Redis Nginx与Lua编写脚本的基本构建块是指令. 指令用于指定何时运行用户Lua代码以及如何使用结果. 下 ...