Python操作MySQL数据库:pymysql连接与数据读写全教程

admin 468次浏览

摘要:在Python后端开发、数据分析等场景中,MySQL是最常用的关系型数据库之一,而pymysql则是Python连接MySQL的主流第三方库。本文将从环境准备、数据

在Python后端开发、数据分析等场景中,MySQL是最常用的关系型数据库之一,而pymysql则是Python连接MySQL的主流第三方库。本文将从环境准备、数据库连接、基础数据读写、事务处理到异常处理,全方位讲解如何用pymysql实现Python与MySQL的交互,内容贴合实际开发场景,新手也能快速上手。

一、前置准备:环境与依赖安装

1. 检查MySQL环境

确保本地或服务器已安装MySQL数据库,且能正常启动。可通过以下命令验证(Windows/Linux通用,需配置MySQL环境变量):

mysql -u root -p

输入密码后能进入MySQL终端,说明环境正常。

2. 安装pymysql库

pymysql不是Python标准库,需通过pip安装,命令如下:

# 基础安装

pip install pymysql

# 指定版本(推荐稳定版)

pip install pymysql==1.1.0

安装完成后,在Python脚本中导入pymysql,无报错即安装成功:

import pymysql

二、核心步骤:Python连接MySQL数据库

1. 基础连接语法

pymysql通过connect()方法创建数据库连接对象,核心参数说明:

参数名

说明

示例

host

MySQL服务器地址

localhost/192.168.1.100

port

端口号,默认3306

3306

user

数据库用户名

root

password

数据库密码

123456

database

要连接的数据库名

test_db

charset

字符编码,推荐utf8mb4

utf8mb4

2. 最简连接示例

import pymysql

# 1. 创建数据库连接

conn = pymysql.connect(

host='localhost',

port=3306,

user='root',

password='你的MySQL密码',

database='test_db',

charset='utf8mb4'

)

# 2. 验证连接(可选)

try:

# 获取游标对象(用于执行SQL)

cursor = conn.cursor()

print("数据库连接成功!")

finally:

# 3. 关闭游标和连接(避免资源泄露)

cursor.close()

conn.close()

3. 连接池优化(生产环境推荐)

频繁创建/关闭连接会消耗资源,生产环境建议使用连接池。这里推荐pymysqlpool(需先安装pip install pymysqlpool):

from pymysqlpool import ConnectionPool

# 配置连接池

pool = ConnectionPool(

host='localhost',

port=3306,

user='root',

password='你的MySQL密码',

database='test_db',

charset='utf8mb4',

max_size=10, # 最大连接数

min_size=2 # 最小连接数

)

# 获取连接

conn = pool.get_connection()

cursor = conn.cursor()

# 用完归还连接

cursor.close()

conn.close()

三、数据读写:增删改查(CRUD)实操

1. 数据查询(SELECT)

查询是最常用的操作,需注意游标执行SQL后,通过fetchone()/fetchall()/fetchmany()获取结果。

示例1:查询单条数据

import pymysql

def query_single_data():

conn = None

cursor = None

try:

# 创建连接

conn = pymysql.connect(

host='localhost',

port=3306,

user='root',

password='你的密码',

database='test_db',

charset='utf8mb4'

)

# 创建游标(指定返回字典格式,更易读)

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 执行查询SQL

sql = "SELECT id, name, age FROM user WHERE id = %s"

cursor.execute(sql, (1,)) # 参数化查询,避免SQL注入

# 获取结果

result = cursor.fetchone()

print("查询结果:", result)

except pymysql.MySQLError as e:

print("查询失败:", e)

finally:

# 关闭资源

if cursor:

cursor.close()

if conn:

conn.close()

if __name__ == '__main__':

query_single_data()

示例2:查询多条数据

def query_multi_data():

conn = None

cursor = None

try:

conn = pymysql.connect(

host='localhost',

port=3306,

user='root',

password='你的密码',

database='test_db',

charset='utf8mb4'

)

cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)

# 查询年龄大于18的用户

sql = "SELECT id, name, age FROM user WHERE age > %s"

cursor.execute(sql, (18,))

# 获取所有结果

results = cursor.fetchall()

print("查询结果总数:", cursor.rowcount)

for row in results:

print(f"ID: {row['id']}, 姓名: {row['name']}, 年龄: {row['age']}")

except pymysql.MySQLError as e:

print("查询失败:", e)

finally:

if cursor:

cursor.close()

if conn:

conn.close()

2. 数据插入(INSERT)

插入数据后需调用conn.commit()提交事务,否则数据不会写入数据库。

def insert_data():

conn = None

cursor = None

try:

conn = pymysql.connect(

host='localhost',

port=3306,

user='root',

password='你的密码',

database='test_db',

charset='utf8mb4'

)

cursor = conn.cursor()

# 单条插入

sql = "INSERT INTO user (name, age, gender) VALUES (%s, %s, %s)"

# 执行SQL并传入参数

cursor.execute(sql, ("张三", 20, "男"))

# 批量插入(效率更高)

data_list = [

("李四", 22, "男"),

("王五", 19, "女")

]

cursor.executemany(sql, data_list)

# 提交事务

conn.commit()

print(f"插入成功,影响行数:{cursor.rowcount}")

except pymysql.MySQLError as e:

# 出错回滚事务

conn.rollback()

print("插入失败:", e)

finally:

if cursor:

cursor.close()

if conn:

conn.close()

3. 数据更新(UPDATE)

def update_data():

conn = None

cursor = None

try:

conn = pymysql.connect(

host='localhost',

port=3306,

user='root',

password='你的密码',

database='test_db',

charset='utf8mb4'

)

cursor = conn.cursor()

# 更新张三的年龄

sql = "UPDATE user SET age = %s WHERE name = %s"

cursor.execute(sql, (21, "张三"))

conn.commit()

print(f"更新成功,影响行数:{cursor.rowcount}")

except pymysql.MySQLError as e:

conn.rollback()

print("更新失败:", e)

finally:

if cursor:

cursor.close()

if conn:

conn.close()

4. 数据删除(DELETE)

def delete_data():

conn = None

cursor = None

try:

conn = pymysql.connect(

host='localhost',

port=3306,

user='root',

password='你的密码',

database='test_db',

charset='utf8mb4'

)

cursor = conn.cursor()

# 删除年龄小于18的用户

sql = "DELETE FROM user WHERE age < %s"

cursor.execute(sql, (18,))

conn.commit()

print(f"删除成功,影响行数:{cursor.rowcount}")

except pymysql.MySQLError as e:

conn.rollback()

print("删除失败:", e)

finally:

if cursor:

cursor.close()

if conn:

conn.close()

四、关键技巧:避免踩坑

1. 防止SQL注入

绝对不要直接拼接SQL字符串,必须使用参数化查询(如上述示例中的%s占位符)。错误示例(禁止使用):

# 危险!易被SQL注入

name = "张三' OR 1=1 --"

sql = f"SELECT * FROM user WHERE name = '{name}'"

cursor.execute(sql)

2. 事务处理

MySQL默认开启事务,增删改操作需commit()提交;出错时用rollback()回滚,保证数据一致性。推荐写法:

try:

# 执行多个SQL操作

cursor.execute(sql1)

cursor.execute(sql2)

conn.commit() # 全部成功才提交

except Exception as e:

conn.rollback() # 有错误则回滚

print("事务失败:", e)

3. 字符编码问题

连接时指定charset='utf8mb4'(而非utf8),utf8mb4支持emoji等特殊字符,避免插入数据时出现编码错误。

4. 资源释放

无论操作成功与否,都要关闭游标和连接。推荐使用with语句自动释放资源,简化代码:

import pymysql

# with语句自动关闭连接和游标

with pymysql.connect(

host='localhost',

port=3306,

user='root',

password='你的密码',

database='test_db',

charset='utf8mb4'

) as conn:

with conn.cursor(cursor=pymysql.cursors.DictCursor) as cursor:

sql = "SELECT * FROM user LIMIT 10"

cursor.execute(sql)

results = cursor.fetchall()

print(results)

五、常见问题排查

1. 连接失败:Access denied for user

检查用户名/密码是否正确;

确认MySQL用户是否允许远程连接(如需远程访问,执行GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '密码'; FLUSH PRIVILEGES;)。

2. 连接超时:TimeoutError

检查MySQL服务器是否启动;

确认防火墙/安全组开放3306端口;

增加连接超时参数:connect_timeout=10。

3. 数据插入后查询不到

未执行conn.commit()提交事务;

检查数据库是否选错(database参数)。

相关文章
友情链接