文章目录
1.数据库介绍
概念:
一个存放数据的仓库(Database),这个仓库按照一定的数据结构组织、存放、管理数据。
分类
关系型数据库:mysql、sql server、oracle、DB2等
非关系型数据库:redis等
python操作数据库的方式
pymysql:纯python开发,支持python2和python3,简单易用
2.数据库基本操作
2.1安装
安装: pip install PyMySQL
验证: pip show PyMySQL
2.2 操作流程
数据库基本操作流程
- 创建连接(connection)
- 获取游标(cursor)
- 执行sql (execute)
- 关闭游标
- 关闭连接
sql基本操作
- 查询操作(select)
- 非查询操作(insert/update/delete)
Q:什么是游标?
- 游标是SQL 的一种数据访问机制,一种数据处理方式;我们可以将“ 游标 ”简单的看成是结果集的一个指针,可以根据需要在结果集上面来回滚动,浏览我需要的数据。
- 原因: 众所周知,使用SQL的select查询操作返回的结果是一个包含一行或者是多行的数据集,如果我们要对查询的结果再进行查询,比如(查看结果的第一行、下一行、最后一行、前十行等等操作)简单的通过select语句是无法完成的,因为这时候索要查询的结果不是数据表,而是已经查询出来的结果集。
2.3数据准备
注意事项
直接使用本地localhost数据库即可
- 请先通过phpstudy启动本地的数据库
- 然后通过Navicat连接本地数据库
- 执行数据库初始化语句
CREATE DATABASE if not EXISTS books DEFAULT charset utf8;
use books;
Drop TABLE if EXISTS `t_book`;
CREATE TABLE `t_book`(
`id` int(11) not null auto_increment,
`title` VARCHAR(20) not NULL COMMENT '图书名称',
`pub_date` date not NULL COMMENT '发布日期',
`read` int(11) not null default '0' comment '阅读量',
`comment` int(11) not null default '0' comment '评论量',
`is_delete` TINYINT(1) not NULL DEFAULT '0' COMMENT '逻辑删除',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='图书表';
INSERT into `t_book` VALUES ('1','射雕英雄传','1980-05-01','12','34','0');
INSERT into `t_book` VALUES ('2','天龙八部','1986-07-24','36','40','0');
INSERT into `t_book` VALUES ('3','笑傲江湖','1995-12-24','20','80','0');
Drop TABLE if EXISTS `t_hero`;
CREATE TABLE `t_hero`(
`id` int(11) not null auto_increment,
`name` VARCHAR(20) not NULL COMMENT '姓名',
`gender` SMALLINT(6) not NULL COMMENT '性别',
`description` VARCHAR(200) default NULL comment '描述',
`is_delete` TINYINT(1) not NULL DEFAULT '0' COMMENT '逻辑删除',
`book_id` int(11) not null comment '所属图书ID',
PRIMARY KEY(`id`),
key `t_hero_book_id`(`book_id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='英雄人物表';
INSERT into `t_hero` VALUES ('1','郭靖','1','降龙十八掌','0','1');
INSERT into `t_hero` VALUES ('2','黄蓉','0','打狗棍法','0','1');
INSERT into `t_hero` VALUES ('3','乔峰','1','降龙十八掌','0','2');
INSERT into `t_hero` VALUES ('4','令狐冲','1','独孤九剑','0','3');
INSERT into `t_hero` VALUES ('5','任盈盈','0','弹琴','0','3');
2.4数据的基本操作
2.4.1 连接数据库并查询数据库版本
navicat中查询数据库版本
python代码
#aim
#连接数据库
#获取版本信息
import pymysql
#创建连接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books"
)
#创建游标
cursor = conn.cursor()
#执行sql
cursor.execute("select version()")
result = cursor.fetchall()
print(result)
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
运行结果
2.4.2 连接数据库执行数据库查询操作
#导包
import pymysql
#建立连接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books")
#建立游标
cursor = conn.cursor()
#执行sql语句
sql1 = "SELECT * FROM t_book;"
cursor.execute(sql1)
#输出结果
print(cursor.fetchall())
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
2.4.3 连接数据库执行数据库插入操作
import pymysql
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books",
autocommit=True
)
cursor = conn.cursor()
sql1 = "INSERT INTO t_book(id,title,pub_date)VALUES(4,'西游记','1986-01-01');"
sql2 = "SELECT * FROM t_book;"
cursor.execute(sql1)
cursor.execute(sql2)
print(cursor.fetchall())
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
2.4.4 连接数据库执行数据库更新操作
#导包
import pymysql
#建立连接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books")
#建立游标
cursor = conn.cursor()
#执行sql语句
sql1 = "UPDATE t_book SET title='八戒转' WHERE id=4"
cursor.execute(sql1)
print(cursor.fetchall())
cursor.close()
conn.close()
3.数据库事务操作
事务的概念
- 基于代码的角度:一段实现了具体业务单元功能的代码,这段代码要么都执行,要么都不执行
- 基于业务的角度:最小的业务单元,要么都成功,要么都失败
特点:ACID
- 原子性:
事务的一系统操作属于一个基本单元;- 一致性:
在数据库看到的结果要么是执行之前的结果,要么是执行之后的结果;- 隔离性:
事务的内部状态对其他事务是不可见的;- 持久性:
通过事务对数据库的数据改变是永久性的;
操作方式
- 自动操作:
autocomimt = True- 手动操作:
提交事务:conn.commit()
回滚事务:conn.rollback()
执行步骤
1.导包
- try: 程序前期,需要执行的代码
2.创建连接对象
3.获取游标对象
4.执行sql
- 在图书表中插入一行数据
- 主动抛出异常
- 在英雄人物表中插入一行数据 调用提交事务:conn.commit() except: 程序出现异常后,处理代码 调用事务回滚:conn.rollback() finally: 程序结束时,需要执行的代码
5.关闭游标
6.关闭连接
try:
print('正常实现业务的代码')
except Exception as e:
print('出现异常以后处理的代码')
print(e)
finally:
print('不管是否出现异常都需要处理的代码')
try:
#创建连接
#获取游标
#执行sql
#提交事务
except Exception as e:
#回滚事务
#打印异常信息
finally:
#关闭游标
#关闭连接
3.1 案例:数据不一致性问题
步骤:
1).连接到数据库(host:localhost user:root password:root database:books),并开启自动提交事务 。
2).新增一条图书数据(id:4 title:西游记 pub_date:1986-01-01 )
3).故意抛出一个异常(模拟代码出现异常)
4).新增一条英雄人物数据(name:孙悟空 gender:1 book_id:4)
import pymysql
#数据初始化
conn = None
cursor = None
#业务处理
try:
#创建连接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books")
#获取游标
cursor = conn.cursor()
#执行sql
sql1 = "insert into t_book(id, title, pub_date) values(5, '西游记', '1986-01-01');"
cursor.execute(sql1)
print(cursor.rowcount)
print("-"*200)
#主动抛出异常
raise Exception("程序出错")
sql2 = "insert into t_hero(name,gender,book_id) values('孙悟空', 1, 4)"
cursor.execute(sql2)
print(cursor.rowcount)
#提交事务
conn.commit()
except Exception as e:
# 回滚数据并打印异常
conn.rollback()
print(e)
finally:
if cursor:
cursor.close()
if conn:
conn.close()
4.数据库工具封装
1、创建连接
2、创建游标
3、执行sql
try:
# 获取游标对象
# 调用游标对象.execute(sql)
# 如果是 查询:
# 返回所有数据
# 否则:
# 提交事务
# 返回受影响的行数
except:
# 回滚事务
# 抛出异常
finally:
# 关闭游标
# 关闭连接
4、关闭游标
5、关闭连接
要用到python的类、私有方法的创建等;
#导包
#创建工具类
#初始化
#创建连接
#获取游标
#执行sql
#关闭游标
#关闭连接
4.1 封装案例
#导包
import pymysql
#创建工具类
class DBUtil():
__conn = None
__cursor = None
# 创建连接
@classmethod
def __get_conn(cls):
if cls.__conn is None:
cls.__conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books")
return cls.__conn
# 获取游标
@classmethod
def __get_cursor(cls):
if cls.__cursor is None:
cls.__cursor = cls.__get_conn().cursor()
return cls.__cursor
# 执行sql
@classmethod
def exe_sql(cls,sql):
try:
cursor = cls.__get_cursor()
cursor.execute(sql)
if sql.split()[0].lower()=="select":
return cursor.fetchall()
else:
cls.__conn.commit()
return cursor.rowcount
except Exception as e:
cls.__conn.rollback()
print(e)
finally:
cls.__close_conn()
cls.__close_cursor()
# 关闭游标
@classmethod
def __close_cursor(cls):
if cls.__cursor:
cls.__cursor.close()
# 关闭连接
@classmethod
def __close_conn(cls):
if cls.__conn:
cls.__conn.close()
from sql_fz import DBUtil
sql = "select * from t_book"
# sql = "insert into t_book(id, title, pub_date) values(4, '西游记', '1986-01-01');"
# sql = "update t_book set title='东游记' where title = '西游记';"
#sql = "delete from t_book where title = '东游记';"
result = DBUtil.exe_sql(sql)
print(result)
执行结果