Python操作数据库之 MySQL
Python操作数据库之MySQL
一、安装Python-MySQLdb模块
Python-MySQLdb是一个操作数据库的模块,Python 通过它对 mysql 数据实现各种操作。
如果要源码安装,可以这里下载: https://pypi.Python.org/pypi/MySQL-Python/
解压安装包,进入解压目录执行以下命令安装
python setup.py install |
ubuntu 下可以这么做:
sudo apt-get install build-essential Python-dev libmysqlclient-dev sudo apt-get install Python-MySQLdb |
pip安装:
pip install mysql-Python |
安装之后,在 python 交互模式下:
>>> import MySQLdb |
如果不报错,恭喜你,已经安装好了。
二、操作数据库
操作数据库流程:
1、导入MySQLdb模块
2、创建数据库连接
3、执行SQL语句和存储过程
4、关闭数据库连接
创建MySQL连接对象
>>> import MySQLdb >>> conn = MySQLdb.connect(host = "localhost" ,user = "root" ,passwd = "123456" ,db = "python" ,port = 3306 ,charset = "utf8" ) >>> |
命令含义解释:
host:等号的后面应该填写 mysql 数据库的地址,因为就数据库就在本机上(也称作本地),所以使用 localhost,注意引号。如果在其它的服务器上,这里应该填写 ip 地址。一般中小型的网站,数据库和程序都是在同一台服务器(计算机)上,就使用 localhost 了。
user:登录数据库的用户名,这里一般填写"root",还是要注意引号。当然,如果读者命名了别的用户名,数据库管理者提供了专有用户名,就更改为相应用户。但是,不同用户的权限可能不同,所以,在程序中,如果要操作数据库,还要注意所拥有的权限。在这里用 root,就放心了,什么权限都有啦。不过,这样做,在大型系统中是应该避免的。
passwd:上述 user 账户对应的登录 mysql 的密码。我在上面的例子中用的密码是"123123"。不要忘记引号。
db:就是刚刚通 create 命令建立的数据库,我建立的数据库名字是"qiwsirtest",还是要注意引号。看官如果建立的数据库名字不是这个,就写自己所建数据库名字。
port:一般情况,mysql 的默认端口是 3306,当 mysql 被安装到服务器之后,为了能够允许网络访问,服务器(计算机)要提供一个访问端口给它。
charset:这个设置,在很多教程中都不写,结果在真正进行数据存储的时候,发现有乱码。这里我将 qiwsirtest 这个数据库的编码设置为 utf-8 格式,这样就允许存入汉字而无乱码了。注意,在 mysql 设置中,utf-8 写成 utf8,没有中间的横线。但是在 Python 文件开头和其它地方设置编码格式的时候,要写成 utf-8。切记!
Python 建立了与数据的连接,其实是建立了一个 MySQLdb.connect() 的实例对象,或者泛泛地称之为连接对象,Python 就是通过连接对象和数据库对话。这个对象常用的方法有:
commit():如果数据库表进行了修改,提交保存当前的数据。当然,如果此用户没有权限就作罢了,什么也不会发生。
rollback():如果有权限,就取消当前的操作,否则报错。
cursor([cursorclass]):返回连接的游标对象。通过游标执行 SQL 查询并检查结果。游标比连接支持更多的方法,而且可能在程序中更好用。
close():关闭连接。此后,连接对象和游标都不再可用了。
创建游标
Python 和数据之间的连接建立起来之后,要操作数据库,就需要让 Python 对数据库执行 SQL 语句。Python 是通过游标执行 SQL 语句的。所以,连接建立之后,就要利用连接对象得到游标对象,方法如下:
>>> cur = conn.cursor() |
此后,就可以利用游标对象的方法对数据库进行操作。那么还得了解游标对象的常用方法:
名称 |
描述 |
close() |
关闭游标。之后游标不可用 |
execute(query[,args]) |
执行一条 SQL 语句,可以带参数 |
executemany(query, pseq) |
对序列 pseq 中的每个参数执行 sql 语句 |
fetchone() |
返回一条查询结果 |
fetchall() |
返回所有查询结果 |
fetchmany([size]) |
返回 size 条结果 |
nextset() |
移动到下一个结果 |
scroll(value,mode='relative') |
移动游标到指定行,如果 mode='relative',则表示从当前所在行移动 value 条,如果 mode='absolute',则表示从结果集的第一行移动 value 条 |
插入数据
>>> cur.execute( "insert into user (name,age,mail) values (%s,%s,%s)" ,( "lulu" , 18 , "lulu@gmail.com" )) 1L >>> |
没有报错,并且返回一个"1L"结果,说明有一n 行记录操作成功。
登录MySQL,验证数据有没有添加成功
mysql> select * from user ; Empty set (0.00 sec) mysql> |
奇怪,并没有看到插入的那条数据!到底哪里错了
特别注意,通过"cur.execute()"对数据库进行操作之后,没有报错,完全正确,但是不等于数据就已经提交到数据库中了,还必须要用到"MySQLdb.connect"连接对象的一个方法:commit(),将数据提交上去,也就是进行了"cur.execute()"操作,要将数据提交,必须执行:
>>> conn.commit() |
再次登录MySQL,看数据有没有添加成功
mysql> select * from user ; + ----+------+------+----------------+ | id | name | age | mail | + ----+------+------+----------------+ | 1 | lulu | 18 | lulu@gmail.com | + ----+------+------+----------------+ 1 row in set (0.00 sec) mysql> |
果然如此。这就如同编写一个文本一样,将文字写到文本上,并不等于文字已经保留在文本文件中了,必须执行"CTRL-S"才能保存。也就是在通过 Python 操作数据库的时候,以"execute()"执行各种 sql 语句之后,要让已经执行的效果保存,必须运行连接对象的"commit()"方法。
插入多条数据
>>> cur.executemany( "insert into user (name,age,mail) values (%s,%s,%s)" ,(( "google" , 25 , "g@gmail.com" ),( "facebook" , 18 , "f@face.book" ),( "github" , 20 , "git@hub.com" ),( "docker" , 10 , "doc@ker.com" ))) 4L >>> |
mysql> select * from user ; + ----+----------+------+----------------+ | id | name | age | mail | + ----+----------+------+----------------+ | 1 | lulu | 18 | lulu@gmail.com | | 2 | google | 25 | g@gmail.com | | 3 | facebook | 18 | f@face.book | | 4 | github | 20 | git@hub.com | | 5 | docker | 10 | doc@ker.com | + ----+----------+------+----------------+ 5 rows in set (0.00 sec) mysql> |
成功插入了多条记录。在"executemany(query, pseq)"中,query 还是一条 sql 语句,但是 pseq 这时候是一个 tuple,这个 tuple 里面的元素也是 tuple,每个 tuple 分别对应 sql 语句中的字段列表。这句话其实被执行多次。只不过执行过程不显示给我们看罢了。
查询
如果要从数据库中查询数据,也用游标方法来操作了。
>>> cur.execute( "select * from user" ) 5L >>> print cur.fetchall() (( 1L , u 'lulu' , 18L , u 'lulu@gmail.com' ), ( 2L , u 'google' , 25L , u 'g@gmail.com' ), ( 3L , u 'facebook' , 18L , u 'f@face.book' ), ( 4L , u 'github' , 20L , u 'git@hub.com' ), ( 5L , u 'docker' , 10L , u 'doc@ker.com' )) >>> |
用cur.execute() 从数据库查询出来的东西,被“保存在了 cur 所能找到的某个地方”,要找出这些被保存的东西,需要用cur.fetchall()(或者 fechone 等),并且找出来之后,做为对象存在。从上面的实验探讨发现,被保存的对象是一个 tuple 中,里面的每个元素,都是一个一个的 tuple。因此,用 for 循环就可以一个一个拿出来了。
再次执行一次上面的操作
>>> print cur.fetchall() () >>> |
为什么结果是空的?
原来是通过游标找出来的对象,在读取的时候有一个特点,就是那个游标会移动。在第一次操作了 print cur.fetchall() 后,因为是将所有的都打印出来,游标就从第一条移动到最后一条。当 print 结束之后,游标已经在最后一条的后面了。接下来如果再次打印,就空了,最后一条后面没有东西了。
再看一个实验
>>> cur.execute( "select * from user" ) 5L >>> print cur.fetchone() ( 1L , u 'lulu' , 18L , u 'lulu@gmail.com' ) >>> print cur.fetchone() ( 2L , u 'google' , 25L , u 'g@gmail.com' ) >>> print cur.fetchone() ( 3L , u 'facebook' , 18L , u 'f@face.book' ) >>> print cur.fetchone() ( 4L , u 'github' , 20L , u 'git@hub.com' ) >>> print cur.fetchone() ( 5L , u 'docker' , 10L , u 'doc@ker.com' ) >>> |
这次不一次全部打印出来了,而是一次打印一条,可以从结果中看出来,果然那个游标在一条一条向下移动
既然在操作存储在内存中的对象时候,游标会移动,能不能让游标向上移动,或者移动到指定位置呢?当然可以,这就是scroll()
123456789 | >>> print cur.fetchone() ( 5L , u 'docker' , 10L , u 'doc@ker.com' ) >>> cur.scroll( - 3 ) >>> print cur.fetchone() ( 3L , u 'facebook' , 18L , u 'f@face.book' ) >>> cur.scroll( 1 ) >>> print cur.fetchone() ( 5L , u 'docker' , 10L , u 'doc@ker.com' )\ >>> |
果然,这个函数能够移动游标,不过请仔细观察,上面的方式是让游标相对与当前位置向上或者向下移动。即:
cur.scroll(n),或者,cur.scroll(n,"relative"):意思是相对当前位置向上或者向下移动,n 为正数,表示向下(向前),n 为负数,表示向上(向后)
还有一种方式,可以实现“绝对”移动,不是“相对”移动:增加一个参数"absolute"
特别提醒看官注意的是,在 Python 中,序列对象是的顺序是从 0 开始的。
>>> cur.scroll( 1 , "absolute" ) 回到序号 1 ,指向第 2 条数据 >>> print cur.fetchone() ( 2L , u 'google' , 25L , u 'g@gmail.com' ) >>> >>> cur.scroll( 0 , "absolute" ) 回到序号 0 ,指向第 1 条数据 >>> print cur.fetchone() ( 1L , u 'lulu' , 18L , u 'lulu@gmail.com' ) >>> |
承接上面操作,继续
>>> print cur.fetchmany( 3 ) (( 2L , u 'google' , 25L , u 'g@gmail.com' ), ( 3L , u 'facebook' , 18L , u 'f@face.book' ), ( 4L , u 'github' , 20L , u 'git@hub.com' )) >>> |
上面这个操作,就是实现了从当前位置(游标指向 tuple 的序号为 1 的位置,即第二条记录)开始,含当前位置,向下列出 3 条记录。
更新数据
更新和插入一样,都需要commit()来提交保存。
>>> cur.execute( "update user set name=%s where id=5" ,( "apple" ,)) 1L >>> cur.execute( "select * from user where id=5" ) 1L >>> print cur.fetchone() ( 5L , u 'apple' , 10L , u 'doc@ker.com' ) >>> |
提交更新
>>> conn.commit() >>> |
最后,关闭游标,关闭连接对象
>>> cur.close() >>> conn.close() >>> |
Python操作数据库之 MySQL的更多相关文章
- python操作数据库(Mysql)
原文地址:https://www.cnblogs.com/R-bear/p/7022231.html python DB-API介绍 1.python标准数据库接口为 python DB-API,py ...
- Python学习笔记(五)之Python操作Redis、mysql、mongodb数据库
操作数据库 一.数据库 数据库类型主要有关系型数据库和菲关系型数据库. 数据库:用来存储和管理数的仓库,数据库是通过依据“数据结构”将数据格式化,以记录->表->库的关系存储.因此数据查询 ...
- python操作数据库
一,安装mysql 如果是windows 用户,mysql 的安装非常简单,直接下载安装文件,双击安装文件一步一步进行操作即可. Linux 下的安装可能会更加简单,除了下载安装包进行安装外,一般的l ...
- 零基础学Python--------第11章 使用Python操作数据库
第11章 使用Python操作数据库 11.1 数据库编程接口 在项目开发中,数据库应用必不可少.虽然数据库的种类有很多,如SQLite.MySQL.Oracle等,但是它们的功能基本都是一样的,为了 ...
- python操作数据库PostgreSQL
1.简述 python可以操作多种数据库,诸如SQLite.MySql.PostgreSQL等,这里不对所有的数据库操作方法进行赘述,只针对目前项目中用到的PostgreSQL做一下简单介绍,主要包括 ...
- Python接口测试实战3(上)- Python操作数据库
如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...
- Python学习笔记 - day11 - Python操作数据库
MySQL的事务 MySQL的事务支持不是绑定在MySQL服务器本身,而是与存储引擎相关,MySQL的两种引擎如下: 1.MyISAM:不支持事务,用于只读程序提高性能 2.InnoDB:支持ACID ...
- 孤荷凌寒自学python第四十四天Python操作 数据库之准备工作
孤荷凌寒自学python第四十四天Python操作数据库之准备工作 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天非常激动地开始接触Python的数据库操作的学习了,数据库是系统化设计 ...
- Python操作数据库及hashlib模块
一.hashlib模块 hashlib模块,主要用于加密相关的操作,在python3的版本里,代替了md5和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA51 ...
随机推荐
- bn两个参数的计算以及layer norm、instance norm、group norm
bn一般就在conv之后并且后面再接relu 1.如果输入feature map channel是6,bn的gamma beta个数是多少个? 6个. 2.bn的缺点: BN会受到batchsize大 ...
- 关于mvn install命令执行报错问题
首先这个报错,通常要么是依赖问题,比如模块之间的依赖传递问题,通常报这种错误会在控制台提示. 或者是比如子工程分为test-entity.test-dao.test-service.test-web三 ...
- ubuntu16.04常见的问题解决方案
问题一:关于咖啡主机和其他服务器厂商和个人虚拟机VM10安装ubuntu16.04 ubuntu16.04默认是没有root用户的,要想有必须要通过用户创建,通常安装ubuntu16.04会有个让你创 ...
- Usaco2008 Jan
[Usaco2008 Jan] https://www.luogu.org/problemnew/show/P2419 题目描述 N (1 ≤ N ≤ 100) cows, conveniently ...
- 【题解】洛谷P4158 [SCOI2009] 粉刷匠(DP)
次元传送门:洛谷P4158 思路 f[i][j][k][0/1]表示在坐标为(i,j)的格子 已经涂了k次 (0是此格子涂错 1是此格子涂对)涂对的格子数 显然的是 每次换行都要增加一次次数 那么当j ...
- P1877 [HAOI2012]音量调节
题目描述 一个吉他手准备参加一场演出.他不喜欢在演出时始终使用同一个音量,所以他决定每一首歌之前他都需要改变一次音量.在演出开始之前,他已经做好一个列表,里面写着每首歌开始之前他想要改变的音量是多少. ...
- haproxy + lvs异同(优点-缺点)
LVS和HAProxy相比,它的异同是什么? 1. 两者都是如软件负载均衡.但lVS是基于linux操作系统实现的一种软负载均衡,Haproxy是根据第三 方应用实现的软负载均衡. 2. LVS是 ...
- 国行ME860刷MIUI3.9.27
刷机前: 系统版本:45.2.3.ME860.ChinaRetail.en.CN Android版本:2.3.4 基带版本:BP_N_01.38.00R WEBtop版本:WT_1.2.0-144_8 ...
- Android :Activity、Adapter、List的初步学习
Activity Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行对手机应用操作. 每个 Activity 都会获得一个用于绘制其用户界面的窗口.窗口一般是会充满屏幕,但也不一定 ...
- 【敏捷实用工具】JIRA介绍以及使用方法
敏捷开发并不是由敏捷工具来推动的.但是没有敏捷工具的支持,就很难进行各种软件工程的相关事件,工具的作用是约束和流程,正确使用敏捷工具可以事半功倍,实践敏捷.近几年来敏捷开发催生大量敏捷工具的产生,在敏 ...