SQLAlchemy介绍与安装 SQLAlchemy常见的基本操作

鳄鱼君

发表文章数:642

Vieu四代商业主题

高扩展、安全、稳定、响应式布局多功能模板。

¥69 现在购买
首页 » Python » SQLAlchemy介绍与安装 SQLAlchemy常见的基本操作

我们经常接触的关系数据库主要有MySQL、Oracle、SQL Server、SQLit和PostgreSQL,操作数据库的方法大致有以下几种:

(1)使用数据库接口连接。在Python的关系数据库连接模式中,分别有pymysql、cx_Oracle,pymssql、sqlite3和psycopg2。基本操作步骤都是连接数据库、执行SQL语句、提交事务、关闭数据库连接。每次操作都需要Open/Close Connection,如此频繁地操作对于整个系统无疑是一种浪费。对于企业应用来说,非常的不科学。


(2)通过ORM(Object/Relation Mapping,对象——关系映射)框架来操作数据库。这是随着面向对象软件开发方法的发展而形成的,面向对象开发方法是当今企业应用开发的主流方法,关系数据库是企业应用级环境汇总永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联继承关系。因此ORM系统一般以中间件的形式存在,主要实现程序对象到关系数据库的映射。

SQLAlchemy框架介绍

常用的ORM框架模块有SQLObject、Stom、Djanjo的ORM、peewee和SQLAlchemy。这里主要介绍SQLAlchemy。SQLAlchemy是Python编程语言下的一款开源软件,提供SQL工具包及对象——关系映射工具,使用MIT许可证发行。

SQLAlchemy采用简单的Python语言,为高效和高性能的数据库访问设计,实现了完整的企业级持久模型。SQLAlchemy的理念是,SQL数据库的量级和性能重要与对象集合,而对象集合的抽象又重要于表和行。因此SQLAlchemy采用类似Java里的Hibernate的数据映射模型,而不是其他ORM框架采用的Active Record模型。

SQLAlchemy在构建与WSGI规范的下一代Python Web框架中得到了广泛应用,是由Mike Bayer及其开发团队开发的一个单独的项目。使用SQLAlchemy等独立ORM的一个优势就是允许开发人员首先考虑数据模型,并能决定稍后可视化数据的方式(采用命令行工具、Web框架还是GUI框架)。这与先决定使用Web框架或GUI框架,再决定如何在框架允许的范围内使用数据库模型的开发方法不同。

SQLAlchemy的安装

使用pip命令直接奥利给:pip install SQLAlchemy,当然你也可以下载whl文件,使用pip命令安装。

使用SQLAlchemy链接数据库实质上还是通过数据库接口实现连接,安装SQLAlchemy之后,还需要安装对应数据库的接口模块,鳄鱼君Ba这里以MySQL为例,使用pip命令安装:pip install pymysql

连接数据库

使用本地数据库,端口默认是3306,是通过MySQL工作台创建并命名为test数据库,也就是MySQL默认有test数据库,就我们就操作它。

SQLAlchemy连接数据库使用数据连接池技术,原理是在系统初始化的时候,将数据库连接作为对象存储在内存当中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕,用户不会将连接关闭,而是将连接放回连接池中,供下一个请求访问使用。而连接的简历、断开都由连接池自身来管理,还可以设置连接池的参数来控制连接池中的初始连接数、连接的上下限及每个连接的最大使用次数、最大空闲时间等等!也可通过其自身的管理机制来监视数据库连接数量、使用情况等。


了解了SQLAlchemy的原理,我们再来看一下SQLAlchemy连接数据库的代码:

from sqlalchemy import create_engine
engine=create_engine("mysql+pymysql://root:123@localhost:3306/test?charset=utf-8",echo=True)

导入SQLAlchemy的create_engine模块,设置数据库指令和参数,就可以实现连接。create_engine的参数说明:

mysql+pymysql://root:110@localhost:3306/test:mysql指明数据库系统类型,pymysql是连接数据库接口的模块,root是数据库系统用户名,123是数据库系统密码,localhost:3306是本地的数据库系统和数据库端口,test是数据库名称。
● echo=True:用于显示SQLAlchemy在操作数据库时所执行的SQL语句情况,相当于一个监视器,可以清楚知道执行情况,如果设置为False,就可以关闭。
● pool_size:设置连接数,默认设置5个连接数,连接数可以根据实际情况进行调整,在一般的爬虫开发中,使用默认值已足够。
● max_overflow:默认连接数为10。当超出最大连接数后,如果超出的连接数在max_overflow设置的访问内,超出的部分还可以继续连接访问,在使用过后,这部分连接不放在pool(连接池)中,而是被真正关闭。
● pool_recycle:连接重置周期,默认为-1,推荐设置为7200,即如果连接已空闲7200秒,就自动重新获取,以防止connection被关闭。
● pool_timeout:连接超时时间,默认为30秒,超过时间的连接都会连接失败。
● ?charset=utf8:对数据库进行编码设置,能对数据库进行中文读写,如果不设置,在进行数据添加、修改和更新等时,就会提示编码错误。

完整的连接数据库代码如下:

from sqlalchemy import create_engine
engine=create_engine("mysql+pymysql://root:123@localhost:3306/test",
    echo=True,pool_size=5,max_overflow=10,pool_recycle=7000,pool_timeout=30)

其它数据的连接:

数据库 连接字符串
Microsoft SQL Server mssql+pymssql://username:password@ip:port/dbname
MySQL mysql+pymysql://username:password@ip:port/dbname
Oracle cx_Oracle://username:password@ip:port/dbname
PostgreSQL postgresql://username:password@ip:port/dbname
SQLite sqlite://file_path

创建数据表

完成数据库连接,接下来就可以通过SQLAlchemy对数据表进行创建和删除。代码参考:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,Integer,String,DateTime
Base=declarative_base()

class mytable(Base):
    # 表名
    __tablename__='mytable'
    # 字段,属性
    id=Column(Integer,primary_key=True)
    name=Column(String(60),unique=True)
    age=Column(Integer)
    birth=Column(DateTime)
    class_name=Column(String(50))
# 创建数据表
Base.metadata.create_all(engine)

首先引入declarative模块,生成Base对象,再创建一个类mytable。一般情况下,数据表名和类名是一致的,__tablename__用于定义数据表的名称,不写默认类名为数据表名。然后创建字段id、name、age、birth、class_name。最后使用Base.metadata.create_all(engine)在数据库中创建对应的数据表。

还有一种类似SQL语句的创建方法:

from sqlalchemy import Column,MetaData,ForeignKey,Table
from sqlalchemy.dialects.mysql import (INTEGER,CHAR)
meta=MetaData()
myclass=Table('myclass',meta
    Column('id',INTEGER,primary_key=True),
    Column('name',CHAR(50),ForeignKey(mytable.name)), 
    Column('class_name',CHAR(50)))
# 创建数据表
myclass.create(bind=engine)

这种方法比较偏向于SQL创建数据表的语法,两者实现的功能都是一样的,按照随意选择。一般情况下,在数据表已经存在的时候,前者再次创建数据表不会报错,后者就会提示数据表错误的信息,所以说前者有一定的优势!

删除数据表

# 先删除myclass,后删除mytable
myclass.drop(bind=engine)
Base.metadata.drop_all(engine)

由于myclass和mytable的name存在关联,所以在删除的时候,一定要先删除设有外键关联的数据表myclass,最后才能删除mytable。

无论数据表是否已经创建,在使用SQLAlchemy时一定要对数据表的属性、字段进行类定义。也就是说,无论通过什么方式创建数据表,在使用SQLAlchemy的时候,第一步是创建数据库连接,第二步是定义类来映射数据表,类的属性映射数据表字段

添加数据

创建数据表后,下一步对数据表进行操作。首先创建一个会话对象,用于执行SQL语句,参考代码:

from sqlalchemy.orm import sessionmaker
DBSession=sessionmaker(bind=engine)
session=DBSession()

引入sessionmaker模块,指明绑定已连接数据库的engine对象,生成会话对象session,该对象用于数据库的增删改查。

以上面的mytable表为例,进行增删改查操作,添加数据

new_data=mytable(name='www.e1yu.com',age=10,birth='1999-01-30',class_name='幼儿园')
session.add(new_data)
session.commint()
session.close()

要使用SQLAlchemy添加数据,必须先定义mytable对象,mytable是映射数据库里面的mytable数据表。然后设置类属性(字段)对应的添加值,将数据绑定在session会话中,最后通过session.commit()来提交到数据中。session.close()用于关闭会话。

添加的数据,你可以在命令行启动mysql看一下,这里不过多介绍!

更新数据

更新上面添加的那条数据,SQLAlchemy提供了两种更新数据的方法:

session.query(mytable).filter_by(id=1).update({mytable.name:'鳄鱼君Ba'})
session.commit()
session.close()

首先查询mytable表id为1的数据;然后使用update对这条数据进行更新,update数据的格式是字典类型,通过键值对的方式对数据进行更新;然后使用session.commit()执行更新语句,最后关闭当前会话。

filter_by相当于SQL语句的where条件,如果想要批量更新,去掉id=1即可,也可以使用赋值的方式更新数据

get_data=session.query(mytable).filter_by(id=1).first()
get_data.class_name='小班'
session.commit()
session.close()

以上方法适用于单条数据更新,如果通过这种方法批量更新,只能循环每条数据进行赋值更改。但这种方法性能影响较大,推荐使用update()

查询数据

SQLAlchemy对数据库多种查询方式有很好的语法支持。这里还是查询mytable数据表。查询所有:

# 查询mytable全部数据
get_data=session.query(myclass).all()
for i in get_data:
    print('我的名字是:'+i.name)
    print('我今年:'+i.age+'岁了')
session.close()

session.query(mytable)相当于SQL语句的select * from mytable;all()是将数据以列表的形式返回。

查询某一字段,SQL语句select name,class_name from mytable;,SQLAlchemy语法:

get_data=session.query(mytable.name,mytable.age).all()
for i in get_data:
    print('我的名字是:'+i.name)
    print('我今年:'+i.age+'岁了')
session.close()

设置筛选条件,SQLAlchemy有两种筛选方法:

# 根据条件查询某条数据
# 方法一
# get_data=session.query(mytable).filter(mytable.id=1).all()
# 方法二
get_data=session.query(mytable).filter_by(id=1).all()
print('数据类型是:%s' % str(type(get_data)))
for i in get_data:
    print('我的名字是:'+i.name)
    print('我今年:'+i.age+'岁了')
session.close()

代码中的filter和filter_by两者区别:
(1)字段写法:filter筛选的字段是带类名(表名)的,而filter_by只需筛选字段即可
(2)判断条件:filter比filter_by多出一个等号
(3)作用范围:filter可用于单表或者多表查询,而filter_by只能用于单表查询

all()方法是将查询数据以列表的形式返回,但如果查询一条数据,可以使用first()方法返回第一条数据。

多条件筛选,例如SQL语法select * from mytable where id>1 and age=10;实现代码参考:

get_data=session.query(mytable).filter(mytable.id>1,mytable.age==10).first()
print('数据类型为:%s' % str(type(get_data)))
print('我的名字是:'+get_data.name)
print('我今年:'+get_data.age+'岁了')

多条件查询只需要在查询条件中添加多个查询内容即可,每个查询内容以英文逗号隔开,如果SQL语句的安定换成or,SQLAlchemy语法如下:

from sqlalchemy import or_
session.query(mytable).filter(or_(mytable.id >1,mytable.age==10 )).first()

涉及到多表查询的内连接查询和外连接查询,代码参考:

# 内连接
get_data=session.query(mytable).join(myclass).filter(
    mytable.class_name=='幼儿园'    
).all()
print('数据类型为:%s' % str(type(get_data)))
for i in get_data:
    print('我的名字是:'+i.name)
    print('我的班级是:'+i.class_name)
# 外连接
get_data=session.query(mytable).outerjoin(myclass).filter(
    mytable.class_name=='幼儿园'    
).all()
session.close()

代码中的join和outerjoin与SQL语句中的INNER JOIN和FULL OUTERJOIN意思一直,两者之间实现功能和性能上存在一些差别。SQLAlchemy还可以直接执行SQL语句,代码参考:

sql='select * from mytable'
session.execute(sql)
# 如果涉及更新、添加数据,就需要session.commit
session.commit()

未经允许不得转载:作者:鳄鱼君, 转载或复制请以 超链接形式 并注明出处 鳄鱼君
原文地址:《SQLAlchemy介绍与安装 SQLAlchemy常见的基本操作》 发布于2020-06-04

分享到:
赞(0) 赏杯咖啡

评论 抢沙发

6 + 7 =


文章对你有帮助可赏作者一杯咖啡

支付宝扫一扫打赏

微信扫一扫打赏

Vieu4.6主题
专业打造轻量级个人企业风格博客主题!专注于前端开发,全站响应式布局自适应模板。
切换注册

登录

忘记密码 ?

您也可以使用第三方帐号快捷登录

Q Q 登 录
微 博 登 录
切换登录

注册