SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作。将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。在写项目的过程中,常常要使用SQLAlchemy操作数据库,同事前期教我很多东西,感谢之余写一篇文章记录使用过的技术,做到心里有数,手上有活。

在开发过程中涉及到的内容:

  1. 联表查询(外键加持)
  2. 联表查询(无外键)
  3. and 多条件与查询
  4. or 多条件或查询
  5. in 包含查询
  6. offset&limit  切片查询

相关查询操作还有:

  1. ~ 取反操作
  2. is_ 空值判断
  3. between
  4. like  模糊查询

最后补充:

  1. 查询数据类型判断
  2. 多表连接方式(全连接,外连接,内连接)

准备工作

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数据查询小集合的更多相关文章

  1. MySQL 数据查询小练习

    作业 # 创建班级表 create table class ( cls_id int auto_increment primary key, cls_name varchar(10) not null ...

  2. 工作流activiti-03数据查询(流程定义 流程实例 代办任务) 以及个人小练习

    在做数据查询的时候通过调用api来查询数据是相当的简单 对分页也进行了封装listPage(0, 4) ;listPage:分页查询 0:表示起始位置,4:表示查询长度 但是公司的框架封装了分页数据  ...

  3. 关系数据库SQL之高级数据查询:去重复、组合查询、连接查询、虚拟表

    前言 接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL ...

  4. 6、SQL Server 数据查询

    一.使用SELECT检索数据 数据查询是SQL语言的中心内容,SELECT 语句的作用是让数据库服务器根据客户要求检索出所需要的信息资料,并按照规定的格式进行整理,返回给客户端. SELECT 语句的 ...

  5. SQL Server 的表数据简单操作(表数据查询)

    --表数据查询----数据的基本查询-- --数据简单的查询--select * | 字段名[,字段名2, ...] from 数据表名 [where 条件表达式] 例: use 商品管理数据库 go ...

  6. 【SQL查询】集合查询之INTERSECT

    [SQL查询]集合查询之INTERSECT 1  BLOG文档结构图 2  前言部分 2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~ ...

  7. SQL Server 数据查询 整理

    一.使用SELECT检索数据 数据查询是SQL语言的中心内容,SELECT 语句的作用是让数据库服务器根据客户要求检索出所需要的信息资料,并按照规定的格式进行整理,返回给客户端. SELECT 语句的 ...

  8. .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 ...

  9. mySQL 教程 第4章 数据查询

    mySQL运算符 这些运算符在SQL查询中用得到. 算数运算符 + 加 - 减 * 乘 / DIV 除 % MOD 取余数 比较运算符 = 等于 <> != 不等于 < <= ...

随机推荐

  1. SQLServer之视图简介

    视图定义 视图是一个虚拟表,其内容由查询定义. 同表一样,视图包含一系列带有名称的列和行数据. 视图在数据库中并不是以数据值存储集形式存在,除非是索引视图. 行和列数据来自由定义视图的查询所引用的表, ...

  2. C#基础知识之字符串比较方法:“==”操作符;RefernceEquals;String.Equals方法;String.Compare方法;String.CompareOrdinal方法。

    一.“==”操作符:String.Equals:ReferenceEquals 方法 1.在编程中实际上我们只需要这两种比较,c#中类型也就这两种 (1)值类型的比较:一般我们就是判断两个值类型实例各 ...

  3. idea spring-boot总结

    1. 按自己重新配置spring-boot pom点进 mybatis-spring-boot-starter ,在要改的里面 <version>3.4.4</version> ...

  4. Redis原理

    RESP协议 支持tcp协议.基本数据类型,比如数组,字符串等,也可支持其他的通信场景. 模拟redis接收传输过来的set数据 //ServerSocket监听6379端口模拟redis publi ...

  5. Entity Framework Core系列之DbContext(删除)

    上一篇我们介绍了Entity Framework Core系列之DbContext(修改),这一篇我们介绍下删除数据 修改实体的方法取决于context是否正在跟踪需要删除的实体. 下面的示例中con ...

  6. OC调用c++函数

    1.调用的时候我明明改成了 .mm  , 也添加了libstdc++.dylib  调用自己(xcode )写的(cocoa static lib )c++  ,编译总是报找不到库里的函数, 最后我在 ...

  7. 控制结构(5): 必经之地(using)

    // 上一篇:局部化(localization) // 下一篇:最近最少使用(LRU) 基于语言提供的基本控制结构,更好地组织和表达程序,需要良好的控制结构. 前情回顾 上一周,我们谈到了分支/卫语句 ...

  8. CodeForces Round #552 Div.3

    A. Restoring Three Numbers 代码: #include <bits/stdc++.h> using namespace std; ]; int a, b, c; i ...

  9. 用Python开发小学二年级口算自动出题程序

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 武汉光谷一小二年级要求家长每天要给小孩出口算题目,让孩子练习. 根据老师出题要求编写了Python程序 ...

  10. LODOP批量打印多页模版进行维护

    批量打印的时候,可以循环多任务,也可以循环多页,很多的时候也可以分页分任务,分组打印.如果是一个任务里的多页相同的模版,一个任务中会有很多打印项,这些打印项在每页中的位置是相同的,如果要调整,调整结果 ...