PyMySQL
最后修改于 2024 年 1 月 29 日
PyMySQL 教程展示了如何使用 PyMySQL 模块在 Python 中编程 MySQL。
PyMySQL
PyMySQL 是一个纯 Python 的 MySQL 客户端库,基于 PEP 249。大多数公共 API 与 mysqlclient 和 MySQLdb 兼容。PyMySQL 可与 MySQL 5.5+ 和 MariaDB 5.5+ 配合使用。
MySQL 是领先的开源数据库管理系统。它是一个多用户、多线程的数据库管理系统。MySQL 在 Web 上尤其受欢迎。
USE testdb; DROP TABLE IF EXISTS cities; CREATE TABLE cities(id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255), population INT); INSERT INTO cities(name, population) VALUES('Bratislava', 432000); INSERT INTO cities(name, population) VALUES('Budapest', 1759000); INSERT INTO cities(name, population) VALUES('Prague', 1280000); INSERT INTO cities(name, population) VALUES('Warsaw', 1748000); INSERT INTO cities(name, population) VALUES('Los Angeles', 3971000); INSERT INTO cities(name, population) VALUES('New York', 8550000); INSERT INTO cities(name, population) VALUES('Edinburgh', 464000); INSERT INTO cities(name, population) VALUES('Berlin', 3671000);
在本教程中,我们使用 cities
表。
PyMySQL 安装
$ sudo pip3 install pymysql
我们使用 pip3
工具来安装 PyMySQL。
PyMySQL 版本示例
在下面的示例中,我们获取 MySQL 的版本。
#!/usr/bin/python import pymysql con = pymysql.connect('localhost', 'user7', 's$cret', 'testdb') try: with con.cursor() as cur: cur.execute('SELECT VERSION()') version = cur.fetchone() print(f'Database version: {version[0]}') finally: con.close()
在 MySQL 中,我们可以使用 SELECT VERSION
来获取 MySQL 的版本。
import pymysql
我们导入 pymysql
模块。
con = pymysql.connect('localhost', 'user7', 's$cret', 'testdb')
我们使用 connect
连接到数据库。我们传递四个参数:主机名、MySQL 用户名、密码和数据库名。
with con.cursor() as cur:
使用 with
关键字,Python 解释器会自动释放资源。它还提供错误处理。我们获取一个游标对象,该对象用于遍历结果集中的记录。
cur.execute('SELECT VERSION()')
我们调用游标的 execute
函数并执行 SQL 语句。
version = cur.fetchone()
fetchone
函数获取查询结果集的下一行,返回一个单一序列,或者在没有更多可用数据时返回 None
。
print(f'Database version: {version[0]}')
我们打印数据库的版本。
finally: con.close()
pymysql
模块不实现连接资源的自动处理;我们需要在 finally 子句中显式地使用 close
关闭连接。
$ ./version.py Database version: 10.3.23-MariaDB-1
PyMySQL fetchAll
fetchAll
方法检索查询结果的所有(剩余)行,并将它们作为序列的序列返回。
#!/usr/bin/python import pymysql con = pymysql.connect('localhost', 'user7', 's$cret', 'testdb') try: with con.cursor() as cur: cur.execute('SELECT * FROM cities') rows = cur.fetchall() for row in rows: print(f'{row[0]} {row[1]} {row[2]}') finally: con.close()
在示例中,我们从数据库表中检索所有城市。
cur.execute('SELECT * FROM cities')
此 SQL 语句从 cities 表中选择所有数据。
rows = cur.fetchall()
fetchall
函数获取所有记录。它返回一个结果集。从技术上讲,它是一个元组的元组。每个内部元组代表表中的一行。
for row in rows: print(f'{row[0]} {row[1]} {row[2]}')
我们将数据逐行打印到控制台。
$ ./fetch_all.py 1 Bratislava 432000 2 Budapest 1759000 3 Prague 1280000 4 Warsaw 1748000 5 Los Angeles 3971000 6 New York 8550000 7 Edinburgh 464000 8 Berlin 3671000
PyMySQL 字典游标
默认游标返回元组的元组形式的数据。当我们使用字典游标时,数据将以 Python 字典的形式发送。这样我们就可以通过列名引用数据。
#!/usr/bin/python import pymysql import pymysql.cursors con = pymysql.connect(host='localhost', user='user7', password='s$cret', db='testdb', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) try: with con.cursor() as cur: cur.execute('SELECT * FROM cities') rows = cur.fetchall() for row in rows: print(row['id'], row['name']) finally: con.close()
在此示例中,我们使用字典游标获取 cities 表的前几行。
con = pymysql.connect(host='localhost', user='user7', password='s$cret', db='testdb', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
在 connect
函数中,我们将 pymysql.cursors.DictCursor
值传递给 cursorclass
参数。
for row in rows: print(row['id'], row['name'])
我们通过 cities 表的列名来引用数据。
PyMySQL 列标题
接下来我们将展示如何打印数据库表中的数据及其列标题。
#!/usr/bin/python import pymysql con = pymysql.connect('localhost', 'user7', 's$cret', 'testdb') try: with con.cursor() as cur: cur.execute('SELECT * FROM cities') rows = cur.fetchall() desc = cur.description print(f'{desc[0][0]:<8} {desc[1][0]:<15} {desc[2][0]:>10}') for row in rows: print(f'{row[0]:<8} {row[1]:<15} {row[2]:>10}') finally: con.close()
列名被视为元数据。它们是从游标对象获得的。
desc = cur.description
游标的 description
属性返回有关查询每个结果列的信息。
print(f'{desc[0][0]:<8} {desc[1][0]:<15} {desc[2][0]:>10}')
在这里,我们打印并格式化表的列名。
for row in rows: print(f'{row[0]:<8} {row[1]:<15} {row[2]:>10}')
我们遍历并打印数据。
$ ./column_headers.py id name population 1 Bratislava 432000 2 Budapest 1759000 3 Prague 1280000 4 Warsaw 1748000 5 Los Angeles 3971000 6 New York 8550000 7 Edinburgh 464000 8 Berlin 3671000
PyMySQL 转义参数
传递给 execute
方法的参数会出于安全原因进行转义;这是为了防止 SQL 注入攻击。
#!/usr/bin/python import pymysql con = pymysql.connect('localhost', 'user7', 's$cret', 'testdb') # user input myid = 4 try: with con.cursor() as cur: cur.execute('SELECT * FROM cities WHERE id=%s', myid) cid, name, population = cur.fetchone() print(cid, name, population) finally: con.close()
在示例中,我们获取具有指定 ID 的行。
cur.execute('SELECT * FROM cities WHERE id=%s', myid)
我们使用由 %s
标记标识的占位符。在执行 SQL 语句之前,值会被绑定到它们的占位符。
$ ./escaped.py 4 Warsaw 1748000
PyMySQL 受影响的行数
rowcount
是一个只读游标属性,它指定最后一个 SELECT、UPDATE 或 INSERT 语句产生的行数。
#!/usr/bin/python import pymysql con = pymysql.connect('localhost', 'user7', 's$cret', 'testdb') try: with con.cursor() as cur: cur.execute('SELECT * FROM cities WHERE id IN (1, 2, 3)') print(f'The query affected {cur.rowcount} rows') finally: con.close()
在示例中,我们有一个选择三行的 SELECT 语句。
print(f'The query affected {cur.rowcount} rows')
我们构建一条消息来显示受影响的行数。
$ ./affected_rows.py The query affected 3 rows
PyMySQL 插入行
使用 INSERT INTO
SQL 语句插入新行。
#!/usr/bin/python import pymysql con = pymysql.connect('localhost', 'user7', 's$cret', 'testdb') city = (9, 'Kiev', 2887000) try: with con.cursor() as cur: cur.execute('INSERT INTO cities VALUES(%s, %s, %s)', (city[0], city[1], city[2])) con.commit() print('new city inserted') finally: con.close()
在示例中,我们将一个新城市插入表中。
cur.execute('INSERT INTO cities VALUES(%s, %s, %s)', (city[0], city[1], city[2])) con.commit()
在 pymysql
中,自动提交默认是关闭的。我们需要调用 commit
来执行更改。
来源
在本文中,我们一直在使用 PyMySQL 模块在 Python 中编程 MySQL 数据库。
作者
列出所有 Python 教程。