Python操作MySQL数据库

一、概述

1.1 Python操作MySQL的常用库

Python操作MySQL数据库有多种选择,各有特点:

库名 特点 适用场景
PyMySQL 纯Python实现,安装简单,兼容性好 通用场景,无需编译
mysql-connector-python MySQL官方驱动,功能完整 企业级应用
SQLAlchemy ORM框架,提供高层次抽象 复杂业务,需要对象映射
aiomysql 异步IO支持 高并发异步应用
MySQLdb C扩展实现,性能高 对性能要求高的场景

1.2 环境准备

bash

复制代码
# 安装PyMySQL
pip install pymysql

# 安装mysql-connector-python
pip install mysql-connector-python

# 安装SQLAlchemy(通常配合PyMySQL使用)
pip install sqlalchemy pymysql

# 验证安装
python -c "import pymysql; print(pymysql.__version__)"

二、PyMySQL基础使用

2.1 连接数据库

python

复制代码
import pymysql

# 方式1:使用参数
connection = pymysql.connect(
    host='localhost',      # 数据库主机地址
    port=3306,             # 端口号,默认3306
    user='root',           # 数据库用户名
    password='your_password',  # 数据库密码
    database='school',     # 数据库名称
    charset='utf8mb4',     # 字符集
    cursorclass=pymysql.cursors.DictCursor  # 返回字典格式结果
)

# 方式2:使用字典参数
config = {
    'host': 'localhost',
    'port': 3306,
    'user': 'root',
    'password': 'your_password',
    'database': 'school',
    'charset': 'utf8mb4',
    'cursorclass': pymysql.cursors.DictCursor
}
connection = pymysql.connect(**config)

# 关闭连接
connection.close()

2.2 使用上下文管理器

python

复制代码
import pymysql

# 推荐:使用with语句自动管理连接
with pymysql.connect(
    host='localhost',
    user='root',
    password='your_password',
    database='school',
    charset='utf8mb4'
) as connection:
    with connection.cursor() as cursor:
        cursor.execute("SELECT VERSION()")
        version = cursor.fetchone()
        print(f"MySQL版本: {version[0]}")

2.3 连接池实现

python

复制代码
import pymysql
from contextlib import contextmanager
from queue import Queue
import threading

class MySQLConnectionPool:
    """简单的MySQL连接池实现"""
    
    def __init__(self, max_connections=10, **db_config):
        self.max_connections = max_connections
        self.db_config = db_config
        self._pool = Queue(maxsize=max_connections)
        self._lock = threading.Lock()
        
        # 初始化连接池
        for _ in range(max_connections):
            self._pool.put(self._create_connection())
    
    def _create_connection(self):
        """创建新连接"""
        return pymysql.connect(**self.db_config)
    
    @contextmanager
    def get_connection(self):
        """获取连接(上下文管理器)"""
        conn = self._pool.get()
        try:
            yield conn
        finally:
            self._pool.put(conn)
    
    def close_all(self):
        """关闭所有连接"""
        while not self._pool.empty():
            conn = self._pool.get()
            conn.close()

# 使用示例
pool = MySQLConnectionPool(
    max_connections=5,
    host='localhost',
    user='root',
    password='your_password',
    database='school',
    charset='utf8mb4'
)

with pool.get_connection() as conn:
    with conn.cursor() as cursor:
        cursor.execute("SELECT * FROM students LIMIT 10")
        results = cursor.fetchall()
        print(results)

# 程序结束时关闭连接池
pool.close_all()

三、数据操作(CRUD)

3.1 创建数据库和表

python

复制代码
import pymysql

def init_database():
    """初始化数据库和表"""
    connection = pymysql.connect(
        host='localhost',
        user='root',
        password='your_password',
        charset='utf8mb4'
    )
    
    try:
        with connection.cursor() as cursor:
            # 创建数据库
            cursor.execute("CREATE DATABASE IF NOT EXISTS school")
            cursor.execute("USE school")
            
            # 创建学生表
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS students (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    name VARCHAR(50) NOT NULL,
                    age TINYINT UNSIGNED,
                    gender ENUM('男', '女', '保密') DEFAULT '保密',
                    score DECIMAL(5,2) DEFAULT 0.00,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )
            """)
            
            # 创建班级表
            cursor.execute("""
                CREATE TABLE IF NOT EXISTS classes (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    class_name VARCHAR(50) NOT NULL,
                    grade VARCHAR(20)
                )
            """)
            
            connection.commit()
            print("数据库和表创建成功")
            
    finally:
        connection.close()

if __name__ == "__main__":
    init_database()

3.2 插入数据(INSERT)

python

复制代码
import pymysql

def insert_single_record():
    """插入单条记录"""
    connection = pymysql.connect(
        host='localhost',
        user='root',
        password='your_password',
        database='school',
        charset='utf8mb4'
    )
    
    try:
        with connection.cursor() as cursor:
            # 方式1:直接拼接(不推荐,有SQL注入风险)
            # cursor.execute(f"INSERT INTO students (name, age) VALUES ('{name}', {age})")
            
            # 方式2:参数化查询(推荐,防止SQL注入)
            sql = "INSERT INTO students (name, age, gender, score) VALUES (%s, %s, %s, %s)"
            cursor.execute(sql, ('张三', 18, '男', 85.5))
            
            connection.commit()
            print(f"插入成功,影响行数: {cursor.rowcount}")
            print(f"自增ID: {cursor.lastrowid}")
            
    finally:
        connection.close()

def insert_multiple_records():
    """批量插入多条记录"""
    connection = pymysql.connect(
        host='localhost',
        user='root',
        password='your_password',
        database='school',
        charset='utf8mb4'
    )
    
    try:
        with connection.cursor() as cursor:
            sql = "INSERT INTO students (name, age, gender, score) VALUES (%s, %s, %s, %s)"
            data = [
                ('李四', 19, '男', 92.0),
                ('王芳', 18, '女', 88.5),
                ('赵强', 20, '男', 76.0),
                ('孙丽', 19, '女', 95.5)
            ]
            
            # executemany用于批量插入
            cursor.executemany(sql, data)
            connection.commit()
            
            print(f"批量插入成功,影响行数: {cursor.rowcount}")
            
    finally:
        connection.close()

def insert_or_update():
    """插入或更新(ON DUPLICATE KEY UPDATE)"""
    connection = pymysql.connect(
        host='localhost',
        user='root',
        password='your_password',
        database='school',
        charset='utf8mb4'
    )
    
    try:
        with connection.cursor() as cursor:
            # 假设id=1的记录已存在
            sql = """
                INSERT INTO students (id, name, age, score) 
                VALUES (%s, %s, %s, %s)
                ON DUPLICATE KEY UPDATE 
                    name = VALUES(name),
                    age = VALUES(age),
                    score = VALUES(score)
            """
            cursor.execute(sql, (1, '张三(更新)', 19, 90.0))
            connection.commit()
            print(f"插入/更新成功")
            
    finally:
        connection.close()

if __name__ == "__main__":
    insert_single_record()
    insert_multiple_records()
相关推荐
这个DBA有点耶3 小时前
NULL不是空——数据库里最反直觉的设计,90%新人踩过的坑
数据库·mysql·代码规范
用户8356290780513 小时前
Python 实现 PDF 文件加密与解密方法
后端·python
用户8356290780513 小时前
使用 Python 冻结与拆分 Excel 窗格教程
后端·python
这个DBA有点耶5 小时前
AI写的SQL跑崩了生产库,这锅谁背?
数据库·人工智能·程序员
镜舟科技6 小时前
Databricks 再提 LTAP,AI 时代的数据底座为何重回大一统叙事?
数据库·架构·agent
Databend7 小时前
从湖仓升级为 Agent 时代的数据控制面,Snowflake 和 Databricks 有哪些布局
大数据·数据库·agent
ClouGence10 小时前
SQL Server CDC 能放到 Always On 备库读吗?一文讲透原理与实践
数据库·sql server
你好潘先生11 小时前
别再记命令了,用 yeero do 说句人话就能跑脚本,而且不烧 token
服务器·python·命令行
Agent_大师12 小时前
WebSocket 行情重连成功,K线缺口不会自动消失
python
荣码12 小时前
LLM结构化输出:让AI返回JSON而不是废话,我踩了4个坑
java·python