Python 中的数据库访问
Python 中的数据库访问用于与数据库交互,使应用程序能够一致地存储、检索、更新和管理数据。支持多种关系数据库管理系统(RDBMS)用于这些任务,每个系统都需要特定的Python包进行连接 −
- GadFly
- MySQL
- PostgreSQL
- Microsoft SQL Server
- Informix
- Oracle
- Sybase
- SQLite
- and many more...
程序执行过程中输入和生成的数据存储在 RAM 中。如果要永久存储,就需要存储在数据库表中。
关系型数据库使用 SQL(结构化查询语言)对数据库表执行插入/删除/更新作。然而,SQL 的实现因数据库类型而异。这会引发不兼容的问题。一个数据库的SQL指令与另一个数据库不匹配。
DB-API(数据库API)
为解决兼容性问题,Python 增强提案(PEP)249 引入了一种称为 DB-API 的标准化接口。该接口为数据库驱动程序提供了一个一致的框架,确保不同数据库系统间的行为一致。它通过建立一套通用的规则和方法,简化了在不同数据库之间切换的过程。

使用 Python 的 SQLite
Python 的标准库包括 sqlite3 模块,这是 SQLite3 数据库的 DB_API兼容驱动。它作为DB-API的参考实现。对于其他类型的数据库,你需要安装相关的Python软件包------
| Database | Python Package |
|---|---|
| Oracle | cx_oracle, pyodbc |
| SQL Server | pymssql, pyodbc |
| PostgreSQL | psycopg2 |
| MySQL | MySQL Connector/Python, pymysql |
使用 SQLite
由于内置的 sqlite3 模块,使用 SQLite 和 Python 非常简单。该过程包括 −
-
**连接建立 −**使用 sqlite3.connect() 创建一个连接对象,提供必要的连接凭证,如服务器名称、端口、用户名和密码。
-
**事务管理 −**连接对象管理数据库作,包括打开、关闭和事务控制(提交或回滚事务)。
-
**光标对象 −**从连接中获取一个光标对象来执行SQL查询。光标作为数据库中CRUD(创建、读取、更新、删除)作的网关。
在本教程中,我们将学习如何使用 Python 访问数据库,如何在 SQLite 数据库中存储 Python 对象的数据,以及如何从 SQLite 数据库中检索数据并使用 Python 程序进行处理。
sqlite3模块
SQLite 是一个无服务器、基于文件的轻量级事务关系数据库。它不需要安装,访问数据库也不需要用户名和密码等凭证。
Python 的 sqlite3 模块包含 SQLite 数据库的 DB-API 实现。该剧由格哈德·赫林(Gerhard Hring)撰写。让我们学习如何用 Python 使用 sqlite3 模块进行数据库访问。
我们先导入 sqlite3 并检查它的版本。
>>> import sqlite3
>>> sqlite3.sqlite_version
'3.39.4'
连接对象
连接对象由 sqlite3 模块中的 connect() 函数设置。该函数的第一个位置参数是表示 SQLite 数据库文件路径(相对或绝对)的字符串。该函数返回一个指向数据库的连接对象。
>>> conn=sqlite3.connect('testdb.sqlite3')
>>> type(conn)
<class 'sqlite3.Connection'>
连接类定义了各种方法。其中之一是返回光标对象的cursor()方法,我们将在下一节介绍。事务控制通过连接对象的commit()和rollback()方法实现。连接类拥有定义自定义函数和用于SQL查询的聚合的重要方法。
光标对象
接下来,我们需要从 连接对象中获取光标对象。当对数据库执行任何CRUD作时,它是你对数据库的句号。连接对象上的Cursor()方法返回该游标对象。
python
>>> cur=conn.cursor()
>>> type(cur)
<class 'sqlite3.Cursor'>
现在我们可以执行所有SQL查询作,借助其exe()方法,光标对象。该方法需要字符串参数,且必须是有效的SQL语句。
创建数据库表
我们现在将在新创建的"testdb.sqlite3"数据库中添加员工表。在接下来的脚本中,我们调用了 exe() 方法,给它一个包含 CREATE TABLE 语句的字符串。
python
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry='''
CREATE TABLE Employee (
EmpID INTEGER PRIMARY KEY AUTOINCREMENT,
FIRST_NAME TEXT (20),
LAST_NAME TEXT(20),
AGE INTEGER,
SEX TEXT(1),
INCOME FLOAT
);
'''
try:
cur.execute(qry)
print ('Table created successfully')
except:
print ('error in creating table')
conn.close()
当上述程序运行时,当前工作目录中会创建带有 Employee 表的数据库。
我们可以通过在 SQLite 控制台中列出数据库中的表格来验证。
python
sqlite> .open mydb.sqlite
sqlite> .tables
Employee
插入操作
当你想将记录创建到数据库表时,必须使用 INSERT操作。
示例
以下示例执行SQL INSERT语句,在EMPLOYEE表中创建记录 −
python
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="""INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
cur.execute(qry)
conn.commit()
print ('Record inserted successfully')
except:
conn.rollback()
print ('error in INSERT operation')
conn.close()
你也可以使用参数替换技术来执行 INSERT 查询,如下 −
python
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="""INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES (?, ?, ?, ?, ?)"""
try:
cur.execute(qry, ('Makrand', 'Mohan', 21, 'M', 5000))
conn.commit()
print ('Record inserted successfully')
except Exception as e:
conn.rollback()
print ('error in INSERT operation')
conn.close()
READ操作
READ操作 对任何数据库意味着从数据库中获取一些有用信息。
一旦数据库连接建立,你就可以对该数据库进行查询。你可以用 fetchone() 方法获取单个记录,或者使用 fetchall() 方法从数据库表获取多个值。
-
fetchone() − 它取查询结果集的下一行。结果集是指当使用光标对象查询表时返回的对象。
-
fetchall() − 它取出结果集中的所有行。如果有些行已经被 从结果集中提取,然后从结果集中检索剩余的行。
-
rowcount − 这是一个只读属性,返回为 受 execute() 方法影响。
示例
在以下代码中,光标对象执行 SELECT * FROM EMPLOYEE 查询。结果集通过 fetchall() 方法得到。我们用for循环打印结果集里的所有记录。
python
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="SELECT * FROM EMPLOYEE"
try:
# Execute the SQL command
cur.execute(qry)
# Fetch all the rows in a list of lists.
results = cur.fetchall()
for row in results:
fname = row[1]
lname = row[2]
age = row[3]
sex = row[4]
income = row[5]
# Now print fetched result
print ("fname={},lname={},age={},sex={},income={}".format(fname, lname, age, sex, income ))
except Exception as e:
print (e)
print ("Error: unable to fecth data")
conn.close()
它将产生以下输出 −
python
fname=Mac,lname=Mohan,age=20,sex=M,income=2000.0
fname=Makrand,lname=Mohan,age=21,sex=M,income=5000.0
更新操作
UPDATE 对任何数据库的作意味着更新一个或多个已存在数据库中的记录。
以下程序更新所有收入=2000的记录。在这里,我们增加了1000的收入。
python
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="UPDATE EMPLOYEE SET INCOME = INCOME+1000 WHERE INCOME=?"
try:
# Execute the SQL command
cur.execute(qry, (1000,))
# Fetch all the rows in a list of lists.
conn.commit()
print ("Records updated")
except Exception as e:
print ("Error: unable to update data")
conn.close()
删除操作
当你想从数据库中删除某些记录时,必须进行删除作。以下是删除所有收入小于2000的员工记录的程序。
python
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="DELETE FROM EMPLOYEE WHERE INCOME<?"
try:
# Execute the SQL command
cur.execute(qry, (2000,))
# Fetch all the rows in a list of lists.
conn.commit()
print ("Records deleted")
except Exception as e:
print ("Error: unable to delete data")
conn.close()
执行事务
事务是一种确保数据一致性的机制。交易具有以下四个性质 −
-
原子性 − 交易要么完成,要么什么都不发生。
-
一致性 − 事务必须以一致状态开始并离开系统 保持稳定的状态。
-
隔离 − 交易的中间结果在当前事务之外不可见。
-
耐久性 − 一旦交易提交,效果是持久的,甚至 系统故障后。

Python DB API 2.0 提供了两种提交或回滚事务的方法。
示例
你已经知道如何实现交易了。这里有一个类似的例子------
python
# Prepare SQL query to DELETE required records
sql = "DELETE FROM EMPLOYEE WHERE AGE > ?"
try:
# Execute the SQL command
cursor.execute(sql, (20,))
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
COMMIT操作
Commit是一个操作,它向数据库发出绿色信号以完成更改,在此操作之后,任何更改都无法恢复。
下面是一个调用commit方法的简单示例。
db.commit()
ROLLBACK 操作
如果您对一个或多个更改不满意,并且希望完全还原这些更改,请使用rollback()方法。
下面是一个调用rollback()方法的简单示例。
python
db.rollback()
PyMySQL 模块
PyMySQL是一个用于从Python连接到MySQL数据库服务器的接口。它实现了Python数据库API v2.0,并包含一个pure-Python MySQL客户端库。PyMySQL的目标是成为MySQLdb的直接替代品。
安装 PyMySQL
在继续之前,请确保您的计算机上安装了PyMySQL。只需在Python脚本中键入以下内容并执行即可:
python
import PyMySQL
如果结果如下,则表示未安装 MySQLdb 模块 −
python
Traceback (most recent call last):
File "test.py", line 3, in <module>
Import PyMySQL
ImportError: No module named PyMySQL
最后一个稳定版本可在 PyPI 上使用,并可随 pip − 安装
python
pip install PyMySQL
注意 − 确保你拥有安装上述模块的root权限。
MySQL 数据库连接
在连接MySQL数据库之前,请确保以下几点------
-
你已经创建了一个数据库 TESTDB。
-
你在 TESTDB 中创建了一个名为 EMPLOYEE 的表。
-
该表包含字段FIRST_NAME、LAST_NAME、年龄、易和收入。
-
用户 ID "testuser" 和密码 "test123" 被设置为访问 TESTDB。
-
Python 模块 PyMySQL 已正确安装在你的机器上。
-
你已经通过MySQL教程来理解MySQL基础知识。
示例
要在早期示例中使用 MySQL 数据库而非 SQLite 数据库,我们需要更改 connect() 函数如下 −
python
import PyMySQL
# Open database connection
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )
除了这一变化外,所有数据库作都可以毫无困难地完成。
处理错误
错误的来源有很多。例如,已执行的SQL语句中的语法错误、连接失败,或调用已取消或已完成的语句句柄的取指方法。
数据库API定义了每个数据库模块中必须存在的若干错误。下表列出了这些例外情况。
| Sr.No. | Exception & Description |
|---|---|
| 1 | Warning Used for non-fatal issues. Must subclass StandardError. |
| 2 | Error Base class for errors. Must subclass StandardError. |
| 3 | InterfaceError Used for errors in the database module, not the database itself. Must subclass Error. |
| 4 | DatabaseError Used for errors in the database. Must subclass Error. |
| 5 | DataError Subclass of DatabaseError that refers to errors in the data. |
| 6 | OperationalError Subclass of DatabaseError that refers to errors such as the loss of a connection to the database. These errors are generally outside of the control of the Python scripter. |
| 7 | IntegrityError Subclass of DatabaseError for situations that would damage the relational integrity, such as uniqueness constraints or foreign keys. |
| 8 | InternalError Subclass of DatabaseError that refers to errors internal to the database module, such as a cursor no longer being active. |
| 9 | ProgrammingError Subclass of DatabaseError that refers to errors such as a bad table name and other things that can safely be blamed on you. |
| 10 | NotSupportedError Subclass of DatabaseError that refers to trying to call unsupported functionality. |