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()
相关推荐
水彩橘子2 小时前
PostgreSQL Streaming Replication 主从
数据库·postgresql
SuperEugene2 小时前
Python 异步 async/await:为什么 AI 框架大量使用?| 基础篇
开发语言·人工智能·python
数厘2 小时前
2.3MySQL 表结构设计:提升 SQL 查询性能的关键
android·sql·mysql
SMF19192 小时前
【uv】Python包管理器uv安装和应用
开发语言·python·uv
gergul2 小时前
在llama-cpp-python中使用自己编译的llama.cpp,解决pip install llama-cpp-python报错
python·llama·llama.cpp·llamacpppython
深蓝轨迹2 小时前
#Python零基础机器学习入门教程
人工智能·python·机器学习
蓝色的杯子2 小时前
Python面试30分钟突击掌握-LeetCode1-Array
开发语言·python·面试
怪祝浙2 小时前
超简洁YOLO8n快速上手人员检测
python
亚马逊云开发者2 小时前
Amazon Aurora PostgreSQL 快速配置实战:两次点击秒级创建无服务器数据库,告别 VPC 子网安全组配置噩梦
数据库·postgresql·serverless