SQLALlchemy数据查询小集合
SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作。将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。在写项目的过程中,常常要使用SQLAlchemy操作数据库,同事前期教我很多东西,感谢之余写一篇文章记录使用过的技术,做到心里有数,手上有活。
在开发过程中涉及到的内容:
- 联表查询(外键加持)
- 联表查询(无外键)
- and 多条件与查询
- or 多条件或查询
- in 包含查询
- offset&limit 切片查询
相关查询操作还有:
- ~ 取反操作
- is_ 空值判断
- between
- like 模糊查询
最后补充:
- 查询数据类型判断
- 多表连接方式(全连接,外连接,内连接)
准备工作
1.sqlalchmey开发环境的搭建
pip install sqlalchemy
2.安装mysql数据库
sudo apt-get install mysql-server
3.创建数据库mydb
create database mydb default charset utf8
创建数据库时一定要加上数据的编码方式,否则无法存入中文。
4.下载mysql的python驱动
apt install MySQL-python
创建模型和数据
创建表结构
定义四张表:Student,Family,House,Car。关系如下:
代码创建过程:
from sqlalchemy import Column,String,create_engine,MetaData,ForeignKey,Integer
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker Base = declarative_base()
meta = MetaData() #定义User对象
class Student(Base):
__tablename__ = 'student'
id = Column(String(20),primary_key=True)
name = Column(String(20)) class Family(Base):
__tablename__ = 'family'
id = Column(String(20),primary_key=True)
member = Column(Integer)
student_id = Column(String(20),ForeignKey('student.id')) class House(Base):
__tablename__ = 'house'
id = Column(String(20),primary_key=True)
location = Column(String(100))
family_id = Column(String(20),ForeignKey('family.id')) class Car(Base):
__tablename__ = 'car'
id = Column(String(20),primary_key=True)
name = Column(String(100))
family_id = Column(String(20)) def create_fun(): #初始数据库连接
engine = create_engine('mysql+mysqldb://root:123@127.0.0.1:3306/mydb?charset=utf8',echo=True)
#创建DBsession
DBSession = sessionmaker(bind=engine) #创建session会话,数据库操作的基石。
session = DBSession() #在数据库中创建表user
Student.metadata.create_all(bind=engine)
Family.metadata.create_all(bind=engine)
House.metadata.create_all(bind=engine) #插入数据
stu_one = Student(id='',name= '悟空')
stu_two = Student(id='',name='贝吉塔')
stu_three = Student(id='',name='比克')
stu_four = Student(id='',name='') #提交数据到session session.add(stu_one)
session.add(stu_two)
session.add(stu_three) session.add(stu_four)
session.commit() family_one = Family(id='',member=7,student_id='')
family_two = Family(id='',member=5,student_id='')
family_three = Family(id='',member=8,student_id='') session.add(family_one)
session.add(family_two)
session.add(family_three)
session.commit() house_one = House(id='',location='地球',family_id='')
house_two = House(id='',location='贝吉塔星',family_id='')
house_three = House(id='',location='美克星人',family_id='')
house_four = House(id='',location='地球',family_id='') session.add(house_one)
session.add(house_two)
session.add(house_three)
session.add(house_four)
session.commit() car_one = Car(id='',name='筋斗云',family_id='')
car_two = Car(id='',name='奔驰',family_id='')
car_three = Car(id='',name='宝马',family_id='') session.add(car_one)
session.add(car_two)
session.add(car_three)
#提交到数据库
session.commit() session.close() if __name__ == '__main__':
create_fun()
创建了四张表,写入了多条数据。
查询
首先来一波基础查询,了解各个表的数据。
student表
Family表
House表
Car表
两张表连表查询
查询Student表,限制条件是Family表中的member字段。Family表外键关联到Student表,查询Family中member 大于6的Student表数据。即家庭成员大于6人的学生表。
result = session.query(Student).join(Family).filter(Family.member>6)
两张表连表查询使用了join关键字。 将Family表添加到Student表中,通过外键关联到一起。通过打印的查询sql语句可以看出,sqlalchemy的join使用的是'INNER JOIN',即内连接方式。可以说,内连接方式是sqlalchemy的默认连接方式。
三张表连表查询
查询Student表,限制的条件是House表中的location字段。
result_two = session.query(Student).join(Family).join(House).filter(House.location=='美克星人')
查询语句使用了两次join,student表连接了family和house。底层的sql查询语句同样使用了INNER JOIN方式。目前三张表的连接方式如下所示:
无外键加持的连表查询
没有外检关联时,使用join关键字连表查询。
result_three = session.query(Student).join(Family).join(Car).filter(Car.name=='宝马')
从报错信息来看,找不到外键关联。这里Car表没有和其他表做外键关联,所有这里找不到关联关系。
无外键的join连表查询
如果建表时使用了外键关联,那么可以直接使用join关键字连接数据库查询。如果没有外键关联,也可以连表查询,只需要指明外键关系即可。
result = session.query(Student).join(Family).join(Car,Car.family_id==Family.id).filter(Car.name=='宝马')
还是上面的查询语句,指明关联字段 Car.family_id==Family.id 。
这样就可以完成连表查询。
or操作
or操作常用于满足多个条件中的一个条件情况下,例如下面一调语句是指满足location是地球,或者member=7的条件。只要这两种条件其中一种满足即可。
result_four = session.query(Student.name,Family.member,House.location).join(Family).join(House).filter(or_(House.location=='地球',Family.member==))
and操作
和or相反的,and是所有的条件必须要满足。上面的例子是指同时满足location是地球,member等于7的条件。所有or有两个结果,and就只有一个结果。
result = session.query(Student.name,Family.member,House.location).join(Family).join(House).filter(and_(House.location=='地球',Family.member==))
in操作
in操作是一个很方便的操作。如果没有in的话,可以用or同样来完成,但是效率会低,代码也不够简洁。如in_((4,5,6))等价于or_(Family.member == 4,Family.member==5,Family.member==6)。数量多的情况下in操作是效率很高的操作。
result_six = session.query(Student.name,Family.member).join(Family).filter(Family.member.in_((,,)))
offset & limit切片操作
之所以将offset和limit放在一起来将,是因为这两位常常是一起出现的。对的,你猜的不错,就是前台分页是使用。抛开后台分页工具,如果熟练使用offset和limit,自己完全可以写一个后台分页器。
#offset。
result_seven = session.query(Student).offset().all()#从指定的下表开始取数据 #limit
result_ten = session.query(Student).limit().all()#指定要取的数据的个数
~ 取反操作
result = session.query(Student.name,Family.member).join(Family).filter(~Family.member.in_((,,)
between
result = session.query(Student).filter(Student.id.between(,))
like 统配
like的参数有两种写法,分别是带%s和不带。使用%来做通配符,带%表示模糊查询;不带表示精确查询
模糊查询
result = session.query(Student).filter(Student.name.like('悟%'))
精确查询
result = session.query(Student).filter(Student.name.like('悟'))
is空值判断
result = session.query(Student).filter(Student.name.is_(None))
查询结果类型分析
result = session.query(Student)
query查询出来的是对象。对象可以继续filter过滤,也可以all取出所有。
result = session.query(Student).all()
all()方法查询出来的是列表。一定要主意在列表是空值的情况下使用取值或者别的操作会造成报错。
result = session.query(Student).filter(id==)
filter查询出来的是对象。对象支持链式操作,一个filter后面可以继续增加多个filter操作。
连接方式
SQLAlchemy 内,外,左,右,全连接
在连表查询时,从打印出来的sql语句可以看出join是使用了内连接的方式来完成的。内连接的连接方式如下,查询两张表中相同的部分。
外链接,也叫左连接。以左边的表为主表,右边的表为副表,将主表中需要的字段全部列出,然后将副表中的数据按照查询条件与其对应起来。使用关键字outerjoin
Family.query.outerjoin(House).all()
右连接,右连接和左连接相反。1.0本不支持
全连接,则是将两个表的需要的字段的数据全排列。全连接比较特殊,使用一个参数full=True 来完成全连接。1.0版本不支持
Student.query(Student.id,Family.member).join(Family,Family.id ==Student.id, full=True)
查询的全部代码
#coding:utf-8 from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine,and_,or_
from sqlalchemy_improve_two import Student,Family,House,Car # print "初始化数据库引擎"
engine = create_engine("mysql+mysqldb://root:123@localhost:3306/mydb?charset=utf8") # print "创建session对象"
DBSession = sessionmaker(bind=engine)
session = DBSession() def select_join(): # result = session.query(Student) # result = session.query(Family) # result = session.query(House) # result = session.query(Car) # print '两张表联表查询'
# print 'Student表joinFamily表,通过查找Family表中member字段大于6的Student表中数据'
# result = session.query(Student).join(Family).filter(Family.member>6) #三张表连表查询
# result = session.query(Student).join(Family).join(House).filter(House.location=='美克星人') #没有外键关系的join查询。car与其他表没有外键关系
# result_three = session.query(Student).join(Family).join(Car).filter(Car.name=='宝马') #在没有外键关联的情况下使用join连接两张表
# result = session.query(Student).join(Family).join(Car,Car.family_id==Family.id).filter(Car.name=='宝马') #or 操作
# result = session.query(Student.name,Family.member,House.location).join(Family).join(House).filter(or_(House.location=='地球',Family.member==7)) #in操作
# result = session.query(Student.name,Family.member).join(Family).filter(Family.member.in_((4,5,6))) #offset
# result = session.query(Student).offset(2) #limit
# result = session.query(Student).limit(2) #~取反操作
# result = session.query(Student.name,Family.member).join(Family).filter(~Family.member.in_((4,5,6))) #between
# result = session.query(Student).filter(Student.id.between(1,2)) #like # result = session.query(Student).filter(Student.name.like('悟%')) # result = session.query(Student).filter(Student.name.like('悟')) #空值判断 # result = session.query(Student).filter(Student.name.is_(None)) # result = session.query(Student) # result = session.query(Student).all() result = session.query(Student).filter(id==1)
# print 'sql语句:'
# print result print 'result的数据类型:'
print type(result) print '查询结果:'
for x in result:
print x.id,x.name if __name__ == "__main__": select_join() # print '关闭数据库连接'
session.close()
SQLALlchemy数据查询小集合的更多相关文章
- MySQL 数据查询小练习
作业 # 创建班级表 create table class ( cls_id int auto_increment primary key, cls_name varchar(10) not null ...
- 工作流activiti-03数据查询(流程定义 流程实例 代办任务) 以及个人小练习
在做数据查询的时候通过调用api来查询数据是相当的简单 对分页也进行了封装listPage(0, 4) ;listPage:分页查询 0:表示起始位置,4:表示查询长度 但是公司的框架封装了分页数据 ...
- 关系数据库SQL之高级数据查询:去重复、组合查询、连接查询、虚拟表
前言 接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL ...
- 6、SQL Server 数据查询
一.使用SELECT检索数据 数据查询是SQL语言的中心内容,SELECT 语句的作用是让数据库服务器根据客户要求检索出所需要的信息资料,并按照规定的格式进行整理,返回给客户端. SELECT 语句的 ...
- SQL Server 的表数据简单操作(表数据查询)
--表数据查询----数据的基本查询-- --数据简单的查询--select * | 字段名[,字段名2, ...] from 数据表名 [where 条件表达式] 例: use 商品管理数据库 go ...
- 【SQL查询】集合查询之INTERSECT
[SQL查询]集合查询之INTERSECT 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~ ...
- SQL Server 数据查询 整理
一.使用SELECT检索数据 数据查询是SQL语言的中心内容,SELECT 语句的作用是让数据库服务器根据客户要求检索出所需要的信息资料,并按照规定的格式进行整理,返回给客户端. SELECT 语句的 ...
- .Net程序员学用Oracle系列(14):子查询、集合查询
1.子查询 1.1.子查询简介 1.2.WITH 子查询 2.集合查询 2.1.UNION 和 UNION ALL 2.2.MINUS 2.3.INTERSECT 2.4.集合运算与 ORDER BY ...
- mySQL 教程 第4章 数据查询
mySQL运算符 这些运算符在SQL查询中用得到. 算数运算符 + 加 - 减 * 乘 / DIV 除 % MOD 取余数 比较运算符 = 等于 <> != 不等于 < <= ...
随机推荐
- Filebeat使用内置的mysql模块收集日志存储到ES集群并使用kibana存储
Filebeat内置了不少的模块,可以直接使用他们对日志进行收集,支持的模块如下: [root@ELK-chaofeng07 logstash]# filebeat modules list Enab ...
- vue 用less
https://blog.csdn.net/u013746071/article/details/79655042
- Java的动态代理
什么是动态代理(dynamic proxy) 动态代理(以下称代理),利用Java的反射技术(Java Reflection),在运行时创建一个实现某些给定接口的新类(也称“动态代理类”)及其实例(对 ...
- 详解Linux双网卡绑定之bond0
1.什么是bond? 网卡bond是通过多张网卡绑定为一个逻辑网卡,实现本地网卡的冗余,带宽扩容和负载均衡,在生产场景中是一种常用的技术.Kernels 2.4.12及以后的版本均供bonding模块 ...
- DEV SIT UAT PET SIM PRD PROD常见环境英文缩写含义
英文缩写 英文 中文 DEV development 开发 SIT System Integrate Test 系统整合测试(内测) UAT User Acceptance Test 用户验收测试 P ...
- 解决 Intellij IDEA Cannot Resolve Symbol ‘XXX’ 问题
1.java类报错 https://blog.csdn.net/qq_32040767/article/details/77096680 2.类对应的依赖没有加载进来.编译器自身的设置和缓存问题类. ...
- 多数据库有序GUID
背景 常见的一种数据库设计是使用连续的整数为做主键,当新的数据插入到数据库时,由数据库自动生成.但这种设计不一定适合所有场景. 随着越来越多的使用Nhibernate.EntityFramework等 ...
- Git以一个远程分支为基础新建一个远程分支(转载)
例如现在有两个分支,master和develop git checkout master //进入master分支git checkout -b frommaster //以master为源创建分支f ...
- python获取list列表随机数据
第一种方法(推荐)适用于随机取一个值, 返回一个值import randomlist1 = ['佛山', '南宁', '北海', '杭州', '南昌', '厦门', '温州']a = random.c ...
- h5-音视频标签
###1. <video>:Html5提供的播放视频的标签 src:资源地址 controls:该属性定义是显示还是隐藏用户控制界面 调用默认控件 ...