ORM(Object Ralational Mapping,对象关系映射),用来把对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中去。咱们在具体的操做实体对象的时候,就不须要再去和复杂的 SQ L 语句打交道,只需简单的操做实体对象的属性和方法。
python
常见的ORM框架mysql
SQLAlchemy:SQLAlchemy 采用了数据映射模式,其工做单元主要使得有必要限制全部的数据库操做代码到一个特定的数据库session,在该session中控制每一个对象的生命周期 。web
SQLObject:是一种流行的对象关系管理器,用于为数据库提供对象接口,其中表为类,行为实例,列为属性。SQLObject包含一个基于Python对象的查询语言,使SQL更抽象,并为应用程序提供了大量的数据库独立性。sql
Storm :是一个介于 单个或多个数据库与Python之间 映射对象的 Python ORM 。为了支持动态存储和取回对象信息,它容许开发者构建跨数据表的复杂查询。Stom中 table class 不须要是框架特定基类 的子类 。每一个table class是 的sqlobject.SQLObject 的子类。
数据库
Django's ORM :由于Django的ORM 是紧嵌到web框架的,因此就算能够也不推荐,在一个独立的非Django的Python项目中使用它的ORM。Django,一个最流行的Python web框架, 有它独有的 ORM。 相比 SQLAlchemy, Django 的 ORM 更吻合于直接操做SQL对象,操做暴露了简单直接映射数据表和Python类的SQL对象 。bash
sqlalchemy是Python ORM的开源框架,使用它能够快速方便的构建数据库模型
服务器
SQLAlchemy框架session
SQLALchemy自己没法操做数据库,须要依赖pymysql第三方模块,Dialect用于和数据API进行交流,根据配置文件的不一样调用不一样的数据库API,从而实现对数据库的操做架构
使用pymysql链接数据库格式:app
mysql
+
pymysql:
/
/
<username>:<password>@<host>
/
<dbname>[?<options>]
#安装
pip install SQLAlchemy
#检查是否安装成功
C:\Users\lsl\Desktop>python
Python 3.7.0rc1 (v3.7.0rc1:dfad352267, Jun 12 2018, 07:05:25) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlalchemy
>>> sqlalchemy.__version__
'1.3.18'复制代码
2.2.1建立链接对象也就是为了链接到本地的数据库
create_engine中的字段的意义介绍:
engine = create_engine('dialect+driver://username:password@host:port/database')
dialect -- 数据库类型
driver -- 数据库驱动选择(个人数据库驱动选择是pymysql,默认会调用MySQLdb,若是运行的时候提示ImportError: No module named 'MySQLdb'/ImportError: No module named 'pymysql',则意味着没有安装你想使用的数据驱动,安装命令:pip install pymysql)
username -- 数据库用户名
password -- 用户密码
host 服务器地址
port 端口
database 数据库
建立链接:
from sqlalchemy import create_engine
# 链接本地test数据库
engine = create_engine('mysql+pymysql://root:root@localhost:3306/testdab',#数据库类型是mysql,采用pymysql数据库驱动来链接,用户名是root,密码也是root,链接本地数据库testdab(链接的数据库要是已存在的,就是你本地已有的数据库)
encoding='utf-8', # 编码格式
echo=True, # 是否开启sql执行语句的日志输出
pool_recycle=-1, # 多久以后对线程池中的线程进行一次链接的回收(重置) (默认为-1),其实session并不会被close
poolclass=NullPool # 无限制链接数
)复制代码
2.2.2 简单查询——使用SQL语句
result = engine.execute("select * from students")//在execute()里的参数是查询的sql语句
print(result.fetchall()) //打印出查询的结果复制代码
2.2.3 建立映射
建立映射后咱们就能够减小sql语句对数据库的操做,而是经过操做咱们创建的与数据库中的数据表的class来对数据库中的数据进行操做。
建立一个py文件来作数据表的映射text2.py
#引入要使用的declarative_base
from sqlalchemy.ext.declarative import declarative_base
#在要映射的数据表students中有id,name两个字段,因此要引入Integer对应id,String对应name
from sqlalchemy import Column, Integer, String
#声名Base
Base = declarative_base()
#User类就是对应于 __tablename__ 指向的表,也就是数据表students的映射
class User(Base):
#students表是我本地数据库testdab中已存在的
__tablename__ = 'students'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64),nullable=False)
__table_args__ = {
"mysql_charset": "utf8"
}复制代码
在要进行操做以前还要建立一下会话,Session的主要目的是创建与数据库的会话,它维护你加载和关联的全部数据库对象。它是数据库查询(Query)的一个入口。在Sqlalchemy中,数据库的查询操做是经过Query对象来实现的。而Session提供了建立Query对象的接口。
# 建立会话
session = sessionmaker(engine)
mySession = session()复制代码
接下来,咱们就能够经过操做User类来操做数据表students
2.2.4 查询
查询students表中全部的数据
result = mySession.query(News).all()
print(result[0])复制代码
查询students表中第一条数据
result = mySession.query(User).first()
print(result.name) #打印对象属性复制代码
经过id查询数据(id=2)
result = mySession.query(User).filter_by(id=2).first()
print(result.name)复制代码
自定义过滤条件
result = mySession.query(User).filter(text("id>:id")).params(id=2).all()复制代码
根据主键查询
result = mySession.query(User).get(2)复制代码
其余查询操做介绍
all()
返回查询到的全部的结果。这个方法比较危险的地方是,若是数据量大且没有使用limit
子句限制的话,全部的结果都会加载到内存中。它返回的是一个列表,若是查询不到任何结果,返回的是空列表。first()
返回查询到的第一个结果,若是没有查询到结果,返回None
。
.scalar()
这个方法与.one_or_none()
的效果同样。 若是查询到不少结果,抛出sqlalchemy.orm.exc.MultipleResultsFound
异常。若是只有一个结果,返回它,没有结果返回None
。one()
若是只能查询到一个结果,返回它,不然抛出异常。没有结果时抛sqlalchemy.orm.exc.NoResultFound
,有超过一个结果时抛sqlalchemy.orm.exc.MultipleResultsFound
。one_or_none()
比起one()
来,区别只是查询不到任何结果时再也不抛出异常而是返回None
。get()
这是个比较特殊的方法。它用于根据主键来返回查询结果,所以它有个参数就是要查询的对象的主键。若是没有该主键的结果返回None
,不然返回这个结果。2.2.5 增长数据(添加一条数据 name=”小红“),注意要commit
user = User(name="小红")
mySession.add(user)
mySession.commit()
复制代码
2.2.6删除数据(根据id进行修改)
mySession.query(User).filter(User.id == 1).delete()
mySession.commit()复制代码
2.2.7修改数据(修改一条数据,把小红的名字修改为小白)
mySession.query(User).filter(User.name=="小红").update({"name":"小白"})
mySession.commit()复制代码
表名:User
1.条件查询
session.query(User).filter(User.name=='张三'){
.all() 查询全部
.one() 查询单个(若是存在多个会异常)
.first() 查询符合条件的第一个
.limit(1).one() limit限制查询,limit(1).one()升级第一个
.count() 查询符合条件的总个数
}
2.主键查询
session.query(User).get(0) 查询主键ID=0
3.offset(n) 限制前面n个,显示后面n+1个
#查询出第三个后面的全部
session.query(User).offset(3).all()
4.slice()切片
#slice(1,3) 与python的slice一致,从0开始 左闭右开,显示1,2两个元素
session.query(User).slice(1,,3).all()
5.order_by() 默认升序
session.query(User).order_by(User.id).all()
6.desc() 降序
session.query(User).order_by(desc(User.id)).all()
7.like 模糊匹配,与sql同样
session.query(User).filter(User.neme.like('%吴')).add()
8.notlike 与7相反
form operator import *
9.in_() 包含
#查询是否包含唐人、吴新喜这个用户的信息
session.query(User).filter(User.name.in_(['唐人','吴新喜'])).all()
10.notin_() 不包含
11.is_ 两种表达方式 None
#查询全部手机号为null的信息
session.query(User).filter(User.phone==None).all()
session.query(User).filter(User.phone.is_(None)).all()
12. isnot()
13. or_ 条件或者关系
#查询name==吴新喜或者唐人的用户信息
session.query(User).filter(or_(User.name=='唐人',User.name=='吴新喜'))
聚合函数
1.count group_by
#查询全部的密码而且计算其相同的个数
from sqlalchemy import func
ssession.query(db_user.psw,func.count(db_user.psw)).group_by(db_user.psw).all()
2.having
having字句可让咱们筛选成组后的各类数据,where字句在聚合前先筛选记录,也就是说做用在group by和having字句前。
而having子句在聚合后对组记录进行筛选。真实表中没有此数据,这些数据是经过一些函数生存。
即先成组在筛选
#查询全部的密码而且计算其相同的个数,having条件相同密码总数大于1的数据
ssession.query(db_user.psw,func.count(db_user.psw)).group_by(db_user.psw).having(func.count(db_user.psw)>1).all()
3.sum
#计算全部id的总和
ssession.query(func.sum(db_user.id)).all()
4.max
#最大的ID
ssession.query(func.max(db_user.id)).all()
5.min
#最小的id
ssession.query(func.min(db_user.id)).all()
6.lable 别名
lable别名不能用在having中
7.extract 提取时间元素
from sqlalchemy import extract复制代码
#import
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import NullPool
#建立链接对象也就是为了链接到本地的数据库
engine = create_engine('mysql+pymysql://root:root@localhost:3306/testdab',
encoding='utf-8', # 编码格式
echo=True, # 是否开启sql执行语句的日志输出
pool_recycle=-1, # 多久以后对线程池中的线程进行一次链接的回收(重置) (默认为-1),其实session并不会被close
poolclass=NullPool # 无限制链接数
)
#声名Base
Base = declarative_base()
# 建立会话
session = sessionmaker(engine)
mySession = session()
# 建立类,继承基类,用基本类型描述数据库结构
class User(Base):
__tablename__ = 'students'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64),nullable=False)
__table_args__ = {
"mysql_charset": "utf8"
}
#sql语句查询
result = engine.execute("select * from students")
print(result.fetchall())
# 查询第一条
result = mySession.query(User).first()
print(result.name) #打印对象属性
# 查询全部
result = mySession.query(User).all()
print(result[0])
# 查询id为2的
result = mySession.query(User).filter_by(id=2).first()
print(result.name)
# 分页查询 0,2
result = mySession.query(User).filter(User.id>1).limit(2).offset(0).all()
print(result)
#插入新数据
user = User(name="小红")
mySession.add(user)
mySession.commit()
result = mySession.query(User).filter_by(name="小红").first()
print(result.name)
#修改已有数据
mySession.query(User).filter(User.name=="小红").update({"name":"小白"})
mySession.commit()
result = mySession.query(User).filter_by(name="小白").first()
print(result.name)
#删除数据
mySession.query(User).filter(User.id == 1).delete()
mySession.commit()
result = mySession.query(User).first()
print(result.name) #打印对象属性复制代码