对于MySQL、Access、Oracle、Sybase、Microdoft SQL Server、SQLite等关系型的数据库,Python都提供了ODBC接口。
Python提供了一个标准接口用于访问关系型的数据库,即Python DB Application Programming Interface(Py-DBAPI)。每种数据库API都需要一个Py-DBAPI封装的实现,几乎所有的数据库接口都有对应的是是实现方法,同时,Python还内置了用于存储和获取数据的工具。
官方文档:https://wiki.python.org/moin/DatabaseInterfaces

一、struct模块

1.1 介绍

官方文档:https://docs.python.org/2/library/struct.html#struct-format-strings
平面数据库(flat database)是文本数据或二进制数据文件。
打开文本数据文件,使用open() 函数就可以。
打开二进制数据文件,使用struct模块,需要用’wb’,’rb’以二进制(字节流)写,读的方式来处理文件;
链接:https://blog.csdn.net/shudaqi2010/article/details/78133120?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-10&spm=1001.2101.3001.4242
struct模块可以处理和操作与系统无关的二进制数据文件,只适合处理小型文件,如果是大型文件,需要用array模块处理。
struct模块将二进制文件的数据与Python结构进行转换,通常是使用C语音所写的接口来完成。

1.2 方法

方法 说明
struct.pack(fmt, v1, v2, …) 按照给定的格式(fmt),把数据转换成字符串(字节流),并将该字符串返回
struct.pack_into(fmt,buffer,offset,v1,v2,… ) 根据给定的格式(fmt),将数据转换成字符串(字节流),并将字节流写入offset开始的buffer中。(buffer为可写的缓冲区,可用array模块)
struct.unpack(fmt,string 根据给定的格式解压缩字符串,结果是一个元组,即使它只包含一个项目。该字符串必须完全包含该格式所需的数据量(必须等于)
struct.unpack_from(fmt,buffer [,offset = 0 ] ) 根据给定的格式解压缩缓冲区。结果是一个元组,即使它只包含一个项目。
struct.calcsize(fmt ) 返回对应于给定格式的结构的大小,返回占用多少字节的内存

1.3 格式化字符串

格式化字符串就是按照特定的方式来打包或解包,用于指定数据类型、控制字节顺序、大小和对齐方式的特殊字符。
端: 数据在存储器中存放顺序的顺序。
分度值,byte,即byte都是按照正常顺序,但是byte组装成的int时byte的顺序则不同。

大端 小端
较低的有效字节存放在较高的存储器地址中,较高的有效字节存放在较低的存储器地址 较高的有效字节存放在较高的存储器地址中,较低的有效字节存放在较低的存储器地址

格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式:

字符 字节顺序 尺寸 对准
@ 本机 本机 本机
= 本机 标准 没有
< 小端 标准 没有
> 大端 标准 没有
! 网络(大端) 标准 没有

格式化字符可以给定它们的类型。
“标准大小”列是指使用标准大小时打包值的大小,以字节为单位;也就是说,当格式字符串中的一个开始’<’,’>’,’!’或 ‘=’。使用本机大小时,打包值的大小取决于平台。

C型 Python类型 标准尺寸
x 填充字节 没有价值
c char 长度为1的字符串 1个
b signed char 整数 1个
B unsigned char 整数 1个
? _Bool 布尔 1个
h short 整数 2
H unsigned short 整数 2
i int 整数 4
I unsigned int 整数 4
l long 整数 4
L unsigned long 整数 4
q long long 整数 8
Q unsigned long long 整数 8
f float 浮动 4
d double 浮动 8
s char[]
p char[]
P void * 整数
  1. _Bool在C99中定义,如果没有这个类型,则将这个类型视为char,一个字节;
  2. q和Q只适用于64位机器;
  3. 每个格式前可以有一个数字,表示这个类型的个数,如s格式表示一定长度的字符串,4s表示长度为4的字符串;4i表示四个int;
  4. P用来转换一个指针,其长度和计算机相关;
  5. f和d的长度和计算机相关;

    1.4 例子

    ```python

    读取二进制文件

    from tkinter import * import tkinter.filedialog import struct

创建应用程序的类

class App: def init(self,master):

  1. ##创建一个label控件
  2. self.label = Label(master)
  3. self.label.pack(anchor=W)
  4. ##创建一个Button控件
  5. self.button = Button(master,text='Start',command=self.getBinaryData)
  6. self.button.pack(anchor = CENTER)
  7. def setBinaryData(self):
  8. ##将数值数据100,200,300,400转换成integer类型的二进制数据
  9. self.bytes = struct.pack("i"*4, 100, 200, 300, 400)
  10. def getBinaryData(self):
  11. self.setBinaryData()
  12. ##将integer类型的二进制数据转换为数值数据100,200,300,400
  13. values = struct.unpack("i"*4, self.bytes)
  14. self.label.config(text=str(values))

创建应用程序窗口

win = Tk() win.title(string = “平面数据库”)

创建应用程序类的实例变量

app = App(win)

开始窗口的事件循环

win.mainloop()

  1. ![image.png](https://cdn.nlark.com/yuque/0/2020/png/407678/1608803936375-118aea70-3c2e-41c7-b8bc-1f34aa6689fd.png#align=left&display=inline&height=106&margin=%5Bobject%20Object%5D&name=image.png&originHeight=106&originWidth=152&size=2932&status=done&style=none&width=152) ![image.png](https://cdn.nlark.com/yuque/0/2020/png/407678/1608803944568-df3d6b02-8aaf-4ef3-bf40-57f8c8a0a288.png#align=left&display=inline&height=106&margin=%5Bobject%20Object%5D&name=image.png&originHeight=106&originWidth=152&size=5427&status=done&style=none&width=152)
  2. <a name="doMjM"></a>
  3. ## 二、SQLite数据库
  4. <a name="z459z"></a>
  5. ### 2.1 介绍
  6. SQLite数据库是一款小型的嵌入式开源数据库软件,没有独立的维护进程,所有的维护都来自于程序本身,不需要作为独立的服务器允许,可以直接在本地允许。<br />它是遵守ACID的关联式数据库管理系统的,能够支持Windows/Linux/Unix等主流的操作系统,同时能够和很多程序语音相结合,egTclC#、PHP、Java等,还有ODBC接口,与Mysql、PostgreSQL相比,处理速度更快。<br />SQLite引擎不是独立于程序之外的独立进程,而是连接到程序中成为它的一个主要部分。<br />主要的通信协议是在编程语言内直接通过API调用,在消耗总量、延迟事件和整体简单上均有积极的作用。<br />整个数据库(定义、表、索引和数据本身)都在宿主主机上,存储在一个单一的文件中。<br />在Python3中,SQLite已经被包装为标准库pySQLite,可以作为模块导入。
  7. <a name="l2bu6"></a>
  8. ### 2.2 连接数据库
  9. 为了使用sqlite3,必须首先创建一个表示数据库的连接对象
  10. ```python
  11. import sqlite3 #导入sqlite2模块
  12. conn = sqlite3.connect("E:\\pythonstduy\\shujuku\\test.db") #如果不存在,创建数据库test.db如果test.db存在,就直接打开,同时创建数据库连接对象conn

connect() 函数返回一个连接对象conn,这个对象是目前和数据库的连接对象,支持的方法:

方法 说明
close() 关闭连接。连接关闭后,连接对象和游标均不可用
commit() 提交事务,保存数据。如果不提交,则不保存数据,数据库中为上次调用commit()方法之后的数据。
ps:数据库需要支持事务,如果数据库不支持事务,这个方法不会起作用
rollback() 回滚挂起的事务,恢复到上次调用commit()方法后的数据状态
cursor() 返回连接的游标对象

2.3 使用游标查询数据库

创建数据库连接对象conn连接到数据库后,需要打开游标(cursor)。
通过Cursor执行SQL语句实现对数据库表的查询、插入、修改、删除等操作。
在sqlite3中,所有SQL语句的执行都要在游标对象的参与下完成,
Cursor对象的主要方法

方法 说明
callproc(name [, params]) 使用给的那个的名称和参数(可选)调用已命名的数据库
execute(sql [,params]) 执行一条SQL语句
executemany(sql [,params]) 执行多条SQL语句
对于所有给定参数执行同一条SQL语句,一般参数是一个序列
fetchone() 从结果中取出一条记录
fetchmany([size]) 从结果中取出多条记录
fetchall() 从结果中取出所有记录
nextset() 跳至下一跳可用的结果集
scroll() 游标滚动
setinputsizes(sizes) 为参数预先定义内存区域
setoutputsizes(size [,col] 为获取的大数据值设置缓冲区大小
close() 关闭游标,游标关闭后,游标将不可用

Cursor对象的属性

属性 说明
description 结果列描述的序列,只读
rowcount 结果中的行数,只读
arraysize fetchmany中返回的行数,默认为1

2.4 实例

  1. ####创建数据库并使用游标查询数据库
  2. import sqlite3 #导入sqlite3模块
  3. conn = sqlite3.connect("E:\\pythonstduy\\shujuku\\school.db") #连接数据库school.db,创建数据库连接对象
  4. cursor = conn.cursor() #打开游标
  5. print("数据库已经打开")
  6. #创建表
  7. cursor.execute('''
  8. CREATE TABLE STUDENT(
  9. ID int primary key not null,
  10. NAME text not null,
  11. Age int not null,
  12. Score int not null,
  13. Address char(50)
  14. )''')
  15. print("创建表成功")
  16. ##插入记录
  17. cursor.execute('''
  18. INSERT INTO STUDENT VALUES(
  19. 1001,'炎',20,665,"山西太原"
  20. )
  21. ''')
  22. cursor.execute('''
  23. INSERT INTO STUDENT VALUES(
  24. 1002,"桓",21,601,"浙江杭州"
  25. )
  26. ''')
  27. cursor.execute('''
  28. INSERT INTO STUDENT VALUES(
  29. 1003,"彻",22,630,"陕西西安"
  30. )
  31. ''')
  32. cursor.execute('''
  33. INSERT INTO STUDENT VALUES(
  34. 1004,"景",20,660,"陕西咸阳"
  35. )
  36. ''')
  37. print("插入数据完成")
  38. conn.commit() #提交当前事务,保存数据
  39. for row in cursor.execute('select * from STUDENT'): #查询表中数据
  40. print(row)
  41. conn.close() #关闭数据连接
  42. ##结果
  43. 数据库已经打开
  44. 创建表成功
  45. 插入数据完成
  46. (1001, '炎', 20, 665, '山西太原')
  47. (1002, '桓', 21, 601, '浙江杭州')
  48. (1003, '彻', 22, 630, '陕西西安')
  49. (1004, '景', 20, 660, '陕西咸阳')
  50. ##使用fetchall() 等方法提取需要的结果
  51. import sqlite3,sys
  52. conn = sqlite3.connect("E:\\pythonstduy\\shujuku\\school.db") #连接数据库school.db,创建数据库连接对象
  53. curs = conn.cursor() #创建一个连接的游标
  54. curs.execute('''
  55. SElECT * FROM STUDENT
  56. WHERE ID = 1001
  57. ''')
  58. names = [f[0] for f in curs.description]
  59. #curs.description是游标对象列描述的序列
  60. for raw in curs.fetchall():
  61. #从结果中读取全部的结果,读取所有的列名
  62. for pair in zip(names, raw):
  63. #将给定的 list 的每一个变成一个元组,用法为 zip(∗list),将列名和内容对应成一个元组对象
  64. print('%s: %s' % pair)
  65. ##结果
  66. ID: 1001
  67. NAME:
  68. Age: 20
  69. Score: 665
  70. Address: 山西太原

三、MySQL数据库

3.1 PyMySQL

Python为操作mysql数据库提供了标准库PyMySQL。
官网:https://pypi.org/project/PyMySQL/
官方文档:https://pymysql.readthedocs.io/en/latest/
下载:
image.png

3.2 连接MySQL数据库

首先需要安装mysql服务器软件
MySQL > = 5.5
MariaDB > = 5.5
然后需要创建空的数据库ffs
image.png
查询目前mysql数据库的版本

  1. import pymysql
  2. #打开数据库连接 参数依次是[IP,用户名,密码,数据库名]
  3. db = pymysql.connect("localhost","root",'1054052026',"ffs")
  4. ##使用cursor() 方法创建一个游标对象
  5. cursor = db.cursor()
  6. #使用execute() 方法执行SQL查询
  7. cursor.execute('''
  8. SELECT VERSION()
  9. ''')
  10. ##使用fetchone() 方法获取单条数据
  11. data = cursor.fetchone()
  12. #输出查询到的数据
  13. print("Database version : %s" % data)
  14. #关闭数据库连接
  15. db.close()
  16. ##结果
  17. Database version : 10.4.12-MariaDB

3.3 创建数据表

  1. import pymysql
  2. #打开数据库连接
  3. db = pymysql.connect("localhost","root",'1054052026',"ffs")
  4. #使用cursor()方法创建一个游标
  5. cursor = db.cursor()
  6. #创建数据表
  7. cursor.execute('''
  8. CREATE TABLE STUDENT(
  9. ID int primary key not null,
  10. NAME text not null,
  11. Age int not null,
  12. Score int not null,
  13. Address char(50))
  14. ''')
  15. print("STUDENT表创建成功")
  16. #关闭数据库连接
  17. db.close()
  18. ##结果
  19. STUDENT表创建成功

image.png

3.4 插入数据

  1. import pymysql
  2. #打开数据库连接
  3. db = pymysql.connect("localhost","root",'1054052026',"ffs")
  4. #使用cursor()方法创建一个游标
  5. cursor = db.cursor()
  6. #SQL语句
  7. sql = "INSERT INTO STUDENT VALUES (1003,'彻',22,630,'陕西西安')"
  8. try:
  9. #执行插入语句
  10. cursor.execute(sql)
  11. #提交到数据库执行
  12. db.commit()
  13. except:
  14. #如果发生错误,回滚数据库
  15. db.rollback()
  16. #关闭数据库连接
  17. db.close()

image.png

3.5 查询数据

方法 说明
fetchone() 获取下一个查询结果集,结果集是一个对象
fetchall() 接收全部的返回结果行
rowcount 一个只读属性,返回执行execute() 方法后影响的行数
  1. import pymysql
  2. #打开数据库连接
  3. db = pymysql.connect("localhost","root",'1054052026',"ffs")
  4. #使用cursor()方法创建一个游标
  5. cursor = db.cursor()
  6. #SQL语句
  7. sql = "select * from STUDENT where ID >'%d' "%(500)
  8. #执行SQL语句
  9. try:
  10. #执行插入语句
  11. cursor.execute(sql)
  12. #curs.description是游标对象列描述的序列
  13. names = [f[0] for f in cursor.description]
  14. #获取所有记录列表
  15. result = cursor.fetchall()
  16. for row in result:
  17. #给定的 list 的每一个变成一个元组,用法为 zip(∗list),将列名和内容对应成一个元组对象
  18. for pair in zip(names,row):
  19. print('%s: %s' % pair)
  20. except:
  21. print("错误:无法查询数据")
  22. ##关闭数据库连接
  23. db.close()
  24. ##结果
  25. ID: 1003
  26. NAME:
  27. Age: 22
  28. Score: 630
  29. Address: 陕西西安

3.6 更新数据

使用UPDATE语句可以更新数据库记录

  1. import pymysql
  2. #打开数据库连接
  3. db = pymysql.connect("localhost","root",'1054052026',"ffs")
  4. #使用cursor()方法创建一个游标
  5. cursor = db.cursor()
  6. #sql语句
  7. sql = "UPDATE STUDENT SET ID = ID +10"
  8. #执行sql语句
  9. try:
  10. #执行更新数据sql语句
  11. cursor.execute(sql)
  12. #提交到数据库执行
  13. db.commit()
  14. except:
  15. #发生错误,回滚数据库
  16. db.rollback()
  17. #关闭数据库连接
  18. db.close()

image.png

3.7 删除数据

使用DELETE语句删除数据表中的数据
drop database 数据库名 —删除数据库的
drop table 表名–删除表的
delete from 表名 where 条件 —删除数据的

  1. import pymysql
  2. #打开数据库连接
  3. db = pymysql.connect("localhost","root",'1054052026',"ffs")
  4. #使用cursor()方法创建一个游标
  5. cursor = db.cursor()
  6. #sql语句
  7. sql = " DELETE FROM STUDENT WHERE ID >'%d' "%(1002)
  8. #执行sql语句
  9. try:
  10. #执行删除数据sql语句
  11. cursor.execute(sql)
  12. #提交到数据库执行
  13. db.commit()
  14. print("删除成功")
  15. except:
  16. #发生错误,回滚数据库
  17. print("错误")
  18. db.rollback()
  19. #关闭数据库连接
  20. db.close()
  21. ##结果
  22. 删除成功

image.png

四、异常

异常 说明
Warning 当有严重警告的时候触发
eg:插入数据时被截断等,必须是StandardError的子类
Error 警告以外所有其他错误类,必须是StandardError的子类
InterfaceError 当有数据库接口模块本身的错误(不是数据库的错误)发生时触发。
必须时Error的子类
DatabaseError 与数据库有关的错误发生时触发,必须是Error的子类
DataError 当有数据处理并发送错误的时候触发,eg:除零错误、数据超范围等。
必须是DatabaseError的错误
OperationalError 指非用户控制的,而是操作数据库时发生的错误,eg:连接意外断开、数据库名未找到、事务处理失败、内存分配错误。
必须是DatabaseError的错误
IntegrityDrrot 完整性相关的错误,eg:外键检查失败等。
必须是DatabaseError的错误
InternalError 数据库的内部错误,eg:游标(curcor)失败、事务同步失败等。
必须是DatabaseError的错误
ProgrammingError 程序错误,eg:数据表(table)没找到或已存在、SQL语句语法错误、参数数量错误等。
必须是DatabaseError的错误