数据库介绍
- 概念:一个存放数据的仓库(Database),这个仓库按照一定的数据结构组织、存放、管理数据
- 分类:
- 关系型数据库:MySQL、SQL server、Oracle、DB2等
- 非关系型数据库:redis等
- python操作数据库的方式
- pymysql:纯python开发,支持python2python3,简单易用
数据库操作基本流程
- 创建链接
- 获取游标
- 执行sql
- 查询操作(select)
- 非查询操作(inset/update/delete)
- 事务提交(连接对象.commit())
- 事务回滚(连接对象.rollback())
- 关闭游标
- 关闭连接
python代码实现pymysql连接数据库:
数据库基本操作
- 连接数据库(host:localhost user:root password:root database:books)
- 获取数据库版本信息:SELECT VERSION()
# 导包
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()
- 数据库查询操作
# 1).连接到数据库(host:localhost user:root password:root database:books)
# 2).查询图书表的数据(包括:图书id、图书名称、阅读量、评论量)
# 3).获取查询结果的总记录数
# 4).获取查询结果的第一条数据
# 5).获取全部的查询结果
# 导包
import pymysql
# 创建链接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books")
# 获取游标
cursor = conn.cursor()
# 执行sql
sql = "select id,title,`read`,`comment` from t_book;"
cursor.execute(sql)
# 3).获取查询结果的总记录数
print("获取的查询结果记录行数为:",cursor.rowcount)
# 4).获取查询结果的第一条数据
print(cursor.fetchone())
# 5).获取全部的查询结果
# 重置游标位置
cursor.rownumber = 0
print(cursor.fetchall())
# 关闭游标
cursor.close()
# 关闭数据库
conn.close()
- 数据库插入操作
# 导包
import pymysql
# 创建链接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books",
autocommit=True)
# 获取游标
cursor = conn.cursor()
# 执行sql
# 新增一条图书数据
sql = "insert into t_book(id,title,pub_date) values(4,'西游记','1986-01-01');"
cursor.execute(sql)
# 3).获取受影响的结果的记录数
print("影响的结果记录数为:",cursor.rowcount)
# 关闭游标
cursor.close()
# 关闭数据库
conn.close()
- 数据库更新操作
"""
1).连接到数据库(host:localhost user:root password:root database:books autocommit:True)
2).更新[西游记]图书名称为(title:东游记)
"""
# 导包
import pymysql
# 创建链接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books",
autocommit=True)
# 获取游标
cursor = conn.cursor()
# 执行sql
sql = "update t_book set title='东游记' where title = '西游记';"
cursor.execute(sql)
print(cursor.rowcount)
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
- 数据库删除操作
"""
1).连接到数据库(host:localhost user:root password:root database:books autocommit:True)
2).删除图书(title:东游记)
"""
# 导包
import pymysql
# 创建链接
conn = pymysql.connect(host="localhost",
port=3306,
user="root",
password="root",
database="books",
autocommit=True)
# 获取游标
cursor = conn.cursor()
# 执行sql
sql = "delete from t_book where title = '东游记';"
cursor.execute(sql)
print(cursor.rowcount)
# 关闭游标
cursor.close()
# 关闭连接
conn.close()
查询与非查询(插入、更新、删除)操作小结
- 相同点:基本操作流程一样
- 创建链接
- 获取游标
- 执行sql
- 关闭游标
- 关闭连接
- 不同点
- 要执行sql语句不一样
- 非查询操作需要开启事务(在创建连接时,指定参数autocommit=True)
事务
- 概念:
- 基于代码的角度:一段实现了具体业务单元功能的代码,这段代码要么都执行,要么都不执行
- 基于业务的角度:最小的业务单元,要么都成功,要么都失败
- 特点
- 原子性:事务中的一系列操作,是最基本的工作单元
- 一致性:在数据库中看到的结果要么是执行前的结果,要么是执行后的结果
- 隔离性:事务的内部状态对其他事务是不可见的
- 持久化:通过事务对数据库中数据做的改变,永久有效
- 代码实现(未手动捕捉异常)
"""
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",
autocommit=False)
# 获取游标
cursor = conn.cursor()
# 执行sql
sql = "insert into t_book(id, title, pub_date) values(4, '西游记', '1986-01-01');"
cursor.execute(sql)
print(cursor.rowcount)
print("--" * 20)
# 主动抛出异常
#raise Exception("程序出错了!")
#4).新增一条英雄人物数据(name:孙悟空 gender:1 book_id:4)
sql = "insert into t_hero(name,gender,book_id) values('孙悟空', 1,4);"
cursor.execute(sql)
print(cursor.rowcount)
# 提交事务
conn.commit()
except Exception as e:
# 回滚数据
conn.rollback()
# 打印异常信息
print(e)
finally:
# 关闭游标
if cursor:
cursor.close()
# 关闭连接
if conn:
conn.close()
- 手动捕捉异常代码:
"""
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",
autocommit=False)
# 获取游标
cursor = conn.cursor()
# 执行sql
sql = "insert into t_book(id, title, pub_date) values(4, '西游记', '1986-01-01');"
cursor.execute(sql)
print(cursor.rowcount)
print("--" * 20)
# 主动抛出异常
raise Exception("程序出错了!")
#4).新增一条英雄人物数据(name:孙悟空 gender:1 book_id:4)
sql = "insert into t_hero(name,gender,book_id) values('孙悟空', 1,4);"
cursor.execute(sql)
print(cursor.rowcount)
# 提交事务
conn.commit()
except Exception as e:
# 回滚数据
conn.rollback()
# 打印异常信息
print(e)
finally:
# 关闭游标
if cursor:
cursor.close()
# 关闭连接
if conn:
conn.close()
封装
- 封装的代码骨架
# 导包
import pymysql
# 创建工具类
class DBUtil():
# 创建连接
@classmethod
def __get_com(cls):
pass
# 获取游标
@classmethod
def __get_cursor(cls):
pass
# 执行sql
@classmethod
def exe_sql(cls,sql):
try:
pass
except Exception as e:
pass
finally:
pass
# 关闭游标
@classmethod
def __close_cursor(cls):
pass
# 关闭连接
@classmethod
def __close_conn(cls):
pass
- 封装的完整代码实现
- 文件test08_dbutil
# 导包
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()
# 调用游标对象的execute方法,执行sql
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_cursor()
# 关闭连接
cls.__close_conn()
# 关闭游标
@classmethod
def __close_cursor(cls):
if cls.__cursor:
cls.__cursor.close()
cls.__cursor = None
# 关闭连接
@classmethod
def __close_conn(cls):
if cls.__conn:
cls.__conn.close()
cls.__conn = None
- 封装代码的使用
- 新建一个文件test09_dbutil_verfy
from test08_dbutil import DBUtil
# 该句可换成任意sql语句
sql = "insert into t_book(id,title,pub_date) values(4,'西游记','1986-01-01');"
result = DBUtil.exe_sql(sql)
print(result)
- 插入成功的运行结果
- Navicat核实结果