【Python 操作 MySQL 数据库】

news2025/5/17 22:01:47

在 Python 中操作 MySQL 数据库主要通过 pymysqlmysql-connector-python 库实现。以下是完整的技术指南,包含连接管理、CRUD 操作和最佳实践:


一、环境准备

1. 安装驱动库
pip install pymysql          # 推荐(纯Python实现)
# 或
pip install mysql-connector-python  # Oracle官方驱动
2. 数据库准备
CREATE DATABASE testdb;
USE testdb;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

二、连接管理

1. 基础连接
import pymysql

# 建立连接
conn = pymysql.connect(
    host='localhost',
    user='root',
    password='your_password',
    database='testdb',
    charset='utf8mb4',
    cursorclass=pymysql.cursors.DictCursor  # 返回字典格式结果
)
2. 上下文管理器(推荐)
with pymysql.connect(host='localhost', user='root', password='your_pwd', database='testdb') as conn:
    with conn.cursor() as cursor:
        # 执行SQL操作
        pass
    # 连接在此处自动提交/回滚(取决于autocommit设置)

三、CRUD 操作

1. 查询数据
def get_user(username):
    try:
        with conn.cursor() as cursor:
            sql = "SELECT * FROM users WHERE username = %s"
            cursor.execute(sql, (username,))
            result = cursor.fetchone()  # 获取单条记录
            return result
    except pymysql.MySQLError as e:
        print(f"数据库错误: {e}")
        return None

user = get_user("john_doe")
print(user)  # 输出: {'id': 1, 'username': 'john_doe', ...}
2. 插入数据
def create_user(username, email):
    try:
        with conn.cursor() as cursor:
            sql = """INSERT INTO users 
                    (username, email) 
                    VALUES (%s, %s)"""
            cursor.execute(sql, (username, email))
            conn.commit()  # 显式提交事务
            return cursor.lastrowid  # 返回自增ID
    except pymysql.IntegrityError:
        print("用户名已存在")
        conn.rollback()
        return None

new_id = create_user("jane_smith", "jane@example.com")
3. 更新数据
def update_email(user_id, new_email):
    try:
        with conn.cursor() as cursor:
            sql = "UPDATE users SET email = %s WHERE id = %s"
            affected_rows = cursor.execute(sql, (new_email, user_id))
            conn.commit()
            return affected_rows > 0
    except pymysql.MySQLError:
        conn.rollback()
        return False
4. 批量操作
def batch_insert(users):
    try:
        with conn.cursor() as cursor:
            sql = "INSERT INTO users (username, email) VALUES (%s, %s)"
            cursor.executemany(sql, users)  # 批量执行
            conn.commit()
            return cursor.rowcount
    except pymysql.MySQLError:
        conn.rollback()
        return 0

batch_insert([
    ("user1", "u1@test.com"),
    ("user2", "u2@test.com")
])

四、高级技巧

1. 连接池管理
from dbutils.pooled_db import PooledDB

pool = PooledDB(
    creator=pymysql,
    maxconnections=10,
    host='localhost',
    user='root',
    password='your_pwd',
    database='testdb'
)

# 使用连接池获取连接
conn = pool.connection()
2. 存储过程调用
with conn.cursor() as cursor:
    cursor.callproc('get_user_stats', (1,))  # 调用存储过程
    result = cursor.fetchall()
3. 事务控制
try:
    with conn.cursor() as cursor:
        # 执行多个操作
        cursor.execute("UPDATE account SET balance = balance - 100 WHERE id = 1")
        cursor.execute("UPDATE account SET balance = balance + 100 WHERE id = 2")
        conn.commit()  # 显式提交事务
except:
    conn.rollback()  # 回滚所有操作

五、安全实践

1. 防止SQL注入
  • 永远使用参数化查询(不要拼接字符串)
    # 正确方式
    cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
    
    # 危险方式(禁用!)
    cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
    
2. 敏感信息处理
  • 使用环境变量存储密码:
    import os
    password = os.getenv('DB_PASSWORD')
    
3. 连接超时设置
conn = pymysql.connect(
    connect_timeout=5,  # 连接超时5秒
    read_timeout=10     # 读取超时10秒
)

六、性能优化

1. 查询优化
  • 添加索引:

    ALTER TABLE users ADD INDEX idx_email (email);
    
  • 使用EXPLAIN分析查询:

    with conn.cursor() as cursor:
        cursor.execute("EXPLAIN SELECT * FROM users WHERE username = %s", ("john",))
        print(cursor.fetchall())
    
2. 结果集处理
  • 分页查询:

    sql = "SELECT * FROM users LIMIT %s OFFSET %s"
    cursor.execute(sql, (page_size, (page-1)*page_size))
    
  • 流式读取(大数据量):

    with conn.cursor(pymysql.cursors.SSCursor) as cursor:  # 使用服务器端游标
        cursor.execute("SELECT * FROM large_table")
        for row in cursor:
            process(row)
    

七、完整示例

import pymysql
from contextlib import contextmanager

@contextmanager
def database_connection():
    conn = pymysql.connect(
        host='localhost',
        user='root',
        password='your_pwd',
        database='testdb',
        charset='utf8mb4'
    )
    try:
        yield conn
    finally:
        conn.close()

def main():
    with database_connection() as conn:
        with conn.cursor() as cursor:
            # 创建用户
            cursor.execute("""
                INSERT INTO users (username, email)
                VALUES (%s, %s)
            """, ("new_user", "user@example.com"))
            user_id = cursor.lastrowid
            
            # 查询用户
            cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
            print(cursor.fetchone())
            
            # 更新记录
            cursor.execute("""
                UPDATE users 
                SET email = %s 
                WHERE id = %s
            """, ("new_email@example.com", user_id))
            
            conn.commit()

if __name__ == "__main__":
    main()

八、故障排查

1. 常见错误码
  • 1045: 访问被拒绝(检查用户名/密码)
  • 2003: 无法连接(检查主机/端口)
  • 1062: 唯一键冲突
  • 1146: 表不存在
2. 日志记录
import logging
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

# 在连接参数中添加
conn = pymysql.connect(..., cursorclass=pymysql.cursors.SSDictCursor,
                       client_flag=pymysql.client.CLIENT.MULTI_STATEMENTS)

通过遵循这些实践,可以构建安全、高效的数据库交互应用。对于复杂场景,建议结合ORM框架(如SQLAlchemy)进行抽象层开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2378013.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ QT图片查看器

private:QList<QString> fs;int i;void MainWindow::on_btnSlt_clicked() {QStringList files QFileDialog::getOpenFileNames(this,"选择图片",".","Images(*.png *.jpg *.bmp)");qDebug()<<files;ui->picList->clear();ui-…

数据集-目标检测系列- 杨桃 数据集 Starfruit>> DataBall

数据集-目标检测系列- 杨桃 数据集 Starfruit&#xff1e;&#xff1e; DataBall * 相关项目 1&#xff09;数据集可视化项目&#xff1a;gitcode: https://gitcode.com/DataBall/DataBall-detections-100s/overview 2&#xff09;数据集训练、推理相关项目&#xff1a;GitH…

【Linux网络】网络套接字编程

套接字编程 一&#xff0c;理解端口号二&#xff0c;初识TCP/UDP协议三&#xff0c;网络字节序四&#xff0c;UDP套接字编程常用API4.1 struct sockaddr类型4.2 socket接口4.3 bind接口4.4 recvfrom4.5 sendto 五&#xff0c;TCP套接字常用API5.1 listen接口5.2 accept接口5.3 …

【data】上海膜拜数据

数据初始样貌 一、数据预处理 1. 数据每5分钟栅格统计 时间数据的处理 path"mobike_shanghai.csv" dfpd.read_csv(path) # 获取时间信息&#xff0c;对于分钟信息&#xff0c;5分钟取整 def time_info(df,col): df[datetime] pd.to_datetime(df[col])df[wee…

DDS(数据分发服务) 和 P2P(点对点网络) 的详细对比

1. 核心特性对比 维度 DDS P2P 实时性 微秒级延迟&#xff0c;支持硬实时&#xff08;如自动驾驶&#xff09; 毫秒至秒级&#xff0c;依赖网络环境&#xff08;如文件传输&#xff09; 架构 去中心化发布/订阅模型&#xff0c;节点自主发现 完全去中心化&#xff0c;节…

【LeetCode 热题 100】动态规划 系列

&#x1f4c1; 70. 爬楼梯 状态标识&#xff1a;爬到第i层楼梯时&#xff0c;有多少种方法。 状态转移方程&#xff1a;dp[i] dp[i-1] dp[i-2]&#xff0c;表示从走一步和走两步的方式。 初始化&#xff1a;dp[1] 1 , dp[2] 2。 返回值&#xff1a;dp[n]&#xff0c;即走到…

计网实验笔记(一)CS144 Lab1

Lab0 ByteStream : 实现一个在内存中的 有序可靠字节流Lab1 StreamReassembler&#xff1a;实现一个流重组器&#xff0c;一个将字节流的字串或者小段按照正确顺序来拼接回连续字节流的模块Lab2 TCPReceiver&#xff1a;实现入站字节流的TCP部分。Lab3 TCPSender&#xff1a;实…

使用 OpenCV 将图像中标记特定颜色区域

在计算机视觉任务中&#xff0c;颜色替换是一种常见的图像处理操作&#xff0c;广泛用于视觉增强、目标高亮、伪彩色渲染等场景。本文介绍一种简单而高效的方式&#xff0c;基于 OpenCV 检测图像中接近某种颜色的区域&#xff0c;并将其替换为反色&#xff08;对比色&#xff0…

智源联合南开大学开源Chinese-LiPS中文多模态语音识别数据集

2025年5月6日&#xff0c;智源研究院在法国巴黎举行的GOSIM全球开源创新论坛上发布Chinese-LIPS中文多模态语音识别数据集&#xff0c;该数据为智源研究院联合南开大学共同构建。 在语音识别技术飞速发展的背景下&#xff0c;多模态语音识别正逐步成为学术界和工业界的研究热点…

RabbitMQ最新入门教程

文章目录 RabbitMQ最新入门教程1.什么是消息队列2.为什么使用消息队列3.消息队列协议4.安装Erlang5.安装RabbitMQ6.RabbitMQ核心模块7.RabbitMQ六大模式7.1 简单模式7.2 工作模式7.3 发布订阅模式7.4 路由模式7.5 主题模式7.6 RPC模式 8.RabbitMQ四种交换机8.1 直连交换机8.2 主…

python爬虫实战训练

前言&#xff1a;哇&#xff0c;今天终于能访问豆瓣了&#xff0c;前几天爬太多次了&#xff0c;网页都不让我访问了&#xff08;要登录&#xff09;。 先来个小练习试试手吧&#xff01; 爬取豆瓣第一页&#xff08;多页同上篇文章&#xff09;所有电影的排名、电影名称、星…

Redis(三) - 使用Java操作Redis详解

文章目录 前言一、创建项目二、导入依赖三、键操作四、字符串操作五、列表操作六、集合操作七、哈希表操作八、有序集合操作九、完整代码1. 完整代码2. 项目下载 前言 本文主要介绍如何使用 Java 操作 Redis 数据库&#xff0c;涵盖项目创建、依赖导入及 Redis 各数据类型&…

【全网首发】解决coze工作流批量上传excel数据文档数据重复的问题

注意&#xff1a;目前方法将基于前一章批量数据库导入的修改&#xff01;&#xff01;&#xff01;&#xff01;请先阅读上篇文章的操作。抄袭注明来源 背景 上一节说的方法可以批量导入文件到数据库&#xff0c;但是无法解决已经上传的条目更新问题。简单来说&#xff0c;不…

xss-labs靶场第11-14关基础详解

前言&#xff1a; 目录 第11关 第12关 第13关前期思路&#xff1a; 第十四关 内容&#xff1a; 第11关 也和上一关一样&#xff0c;什么输入框都没有&#xff0c;也就是 也是一样的操作&#xff0c;先将这里的hidden属性删掉一个&#xff0c;注意是删掉一个 输入1111&a…

ConcurrentSkipListMap的深入学习

目录 1、介绍 1.1、线程安全 1.2、有序性 1.3、跳表数据结构 1.4、API 提供的功能 1.5、高效性 1.6、应用场景 2、数据结构 2.1、跳表&#xff08;Skip List&#xff09; 2.2、节点类型&#xff1a; 1.Node 2.Index 3.HeadIndex 2.3、特点 3、选择层级 3.1、随…

XML简要介绍

实际上现在的Java Web项目中更多的是基于springboot开发的&#xff0c;所以很少再使用xml去配置项目。所以我们的目的就是尽可能快速的去了解如何读懂和使用xml文件&#xff0c;对于DTD&#xff0c;XMLSchema这类约束的学习可以放松&#xff0c;主要是确保自己知道这里面的大致…

什么是直播美颜SDK?美颜技术底层算法科普

当下&#xff0c;不论是社交直播、电商直播&#xff0c;还是线上教学、虚拟主播场景&#xff0c;都离不开美颜技术的加持。虽然大家在日常使用直播APP时经常体验到美颜效果&#xff0c;但背后的技术原理却相对复杂。本篇文章小编将为大家揭开直播美颜SDK的神秘面纱&#xff0c;…

【pbootcms】打开访问首页显示未检测到您服务器环境的sqlite3数据库拓展,请检查php.ini中是否已经开启该拓展

【pbootcms】新建网站&#xff0c;新放的程序&#xff0c;打开访问首页显示未检测到您服务器环境的sqlite3数据库拓展&#xff0c;请检查php.ini中是否已经开启该拓展。 检查目前网站用到哪个版本的php&#xff0c;然后打开相关文件。 修改一下内容&#xff1a; 查找sqlite3,…

MySQL——十、InnoDB引擎

MVCC 当前读&#xff1a; 读取的是记录的最新版本&#xff0c;读取时还要保证其他并发事务不能修改当前记录&#xff0c;会对读取的记录进行加锁。 -- 当前读 select ... lock in share mode(共享锁) select ... for update update insert delete (排他锁)快照读&#xff1a;…

visual studio生成动态库DLL

visual studio生成动态库DLL 创建动态库工程 注意 #include “pch.h” 要放在上面 完成后点击生成 创建一个控制台项目 设置项目附加目录为刚才创建的动态库工程Dll1&#xff1a; 配置附加库目录&#xff1a; 配置动态库的导入库&#xff08;.lib&#xff09;&#xff1a;链…