1. Python 操作 MySQL 需要安装什么第三方库?分别写出安装命令

常用库

  1. pymysql(纯Python实现)

  2. mysql-connector-python(官方驱动)

  3. SQLAlchemy(ORM框架)

安装命令

bash

pip install pymysql
pip install mysql-connector-python
pip install sqlalchemy

2. 用pymysql库写出 Python 连接 MySQL 的核心代码

python

import pymysql

# 建立数据库连接
conn = pymysql.connect(
    host='localhost',      # 数据库主机地址
    user='root',           # 用户名
    password='123456',     # 密码
    database='test_db',    # 数据库名
    port=3306,             # 端口号
    charset='utf8mb4'      # 字符集
)

# 测试连接
try:
    print("连接成功")
    cursor = conn.cursor()
    cursor.execute("SELECT VERSION()")
    version = cursor.fetchone()
    print(f"MySQL版本:{version[0]}")
finally:
    conn.close()  # 关闭连接

3. 连接MySQL时各参数的含义

  • host:MySQL服务器地址(本地为localhost或127.0.0.1)

  • user:登录用户名

  • password:登录密码

  • database:要连接的数据库名称

  • port:MySQL服务端口号

默认端口:3306

4. 为什么用完MySQL连接后必须关闭?更优雅的方式

必须关闭的原因

  • 释放数据库服务器资源

  • 避免达到最大连接数限制

  • 防止内存泄漏

  • 保持连接池的可用性

更优雅的方式(使用上下文管理器):

python

import pymysql
from contextlib import closing

# 方式1:使用with语句(需要pymysql支持)
with pymysql.connect(
    host='localhost',
    user='root',
    password='123456',
    database='test_db'
) as conn:
    with conn.cursor() as cursor:
        cursor.execute("SELECT * FROM user")
        result = cursor.fetchall()
    # 自动关闭游标和连接

# 方式2:使用closing
with closing(pymysql.connect(
    host='localhost',
    user='root',
    password='123456',
    database='test_db'
)) as conn:
    with closing(conn.cursor()) as cursor:
        cursor.execute("SELECT * FROM user")
        result = cursor.fetchall()

5. execute()和executemany()的区别

  • execute():执行单条SQL语句

  • executemany():执行同一条SQL语句多次,用于批量操作

python

# execute() - 插入单条数据
cursor.execute(
    "INSERT INTO user(name, age) VALUES(%s, %s)",
    ('张三', 20)
)

# executemany() - 批量插入多条数据
data = [
    ('李四', 21),
    ('王五', 22),
    ('赵六', 23)
]
cursor.executemany(
    "INSERT INTO user(name, age) VALUES(%s, %s)",
    data
)

6. 查询类和修改类SQL获取结果的区别

python

# 查询类SQL(SELECT)
cursor.execute("SELECT * FROM user WHERE age > 18")
results = cursor.fetchall()  # 需要获取结果集

# 修改类SQL(INSERT/UPDATE/DELETE)
cursor.execute(
    "UPDATE user SET age = %s WHERE id = %s",
    (25, 1)
)
conn.commit()  # 需要提交事务
affected_rows = cursor.rowcount  # 获取受影响的行数

7. 什么是SQL注入?如何避免

SQL注入:通过在输入中嵌入恶意SQL代码,篡改原SQL语句的执行逻辑。

注入示例

python

# 危险写法(容易SQL注入)
name = "小明' OR '1'='1"
cursor.execute(f"SELECT * FROM user WHERE name = '{name}'")
# 实际执行:SELECT * FROM user WHERE name = '小明' OR '1'='1'

# 安全写法(参数化查询)
name = "小明' OR '1'='1"
cursor.execute(
    "SELECT * FROM user WHERE name = %s",
    (name,)
)
# 参数会被转义,不会执行SQL注入

8. 查询user表所有字段的核心代码

python

import pymysql

# 创建连接
conn = pymysql.connect(
    host='localhost',
    user='root',
    password='123456',
    database='test_db'
)

try:
    # 创建游标
    cursor = conn.cursor()
    
    # 执行SQL查询
    sql = "SELECT * FROM user"
    cursor.execute(sql)
    
    # 获取所有结果
    results = cursor.fetchall()
    
    # 打印结果
    for row in results:
        print(row)
        
finally:
    cursor.close()
    conn.close()

9. 批量插入3条用户数据的实现

python

import pymysql

conn = pymysql.connect(
    host='localhost',
    user='root',
    password='123456',
    database='test_db'
)

try:
    cursor = conn.cursor()
    
    # 准备批量数据
    users_data = [
        (1, '张三', 20),
        (2, '李四', 21),
        (3, '王五', 22)
    ]
    
    # 批量插入
    sql = "INSERT INTO user(id, name, age) VALUES(%s, %s, %s)"
    cursor.executemany(sql, users_data)
    
    # 提交事务
    conn.commit()
    print(f"成功插入 {cursor.rowcount} 条数据")
    
except Exception as e:
    conn.rollback()  # 出错回滚
    print(f"插入失败:{e}")
    
finally:
    cursor.close()
    conn.close()

10. 插入一条数据的完整代码

python

import pymysql

def insert_user():
    """插入一条用户数据"""
    conn = None
    cursor = None
    try:
        # 连接数据库
        conn = pymysql.connect(
            host='localhost',
            user='root',
            password='123456',
            database='test_db'
        )
        
        # 创建游标
        cursor = conn.cursor()
        
        # 插入数据
        sql = "INSERT INTO user(name, age) VALUES(%s, %s)"
        data = ('小明', 20)
        
        cursor.execute(sql, data)
        
        # 提交事务
        conn.commit()
        
        print(f"插入成功,影响行数:{cursor.rowcount}")
        print(f"新记录的ID:{cursor.lastrowid}")
        
    except Exception as e:
        if conn:
            conn.rollback()
        print(f"插入失败:{e}")
        
    finally:
        if cursor:
            cursor.close()
        if conn:
            conn.close()

# 调用函数
insert_user()

11. 根据id查询单条数据

python

import pymysql

def get_user_by_id(user_id):
    """根据ID查询用户"""
    conn = pymysql.connect(
        host='localhost',
        user='root',
        password='123456',
        database='test_db'
    )
    
    try:
        cursor = conn.cursor()
        
        # 查询SQL
        sql = "SELECT id, name, age FROM user WHERE id = %s"
        cursor.execute(sql, (user_id,))
        
        # 获取单条数据
        user = cursor.fetchone()
        
        if user:
            print(f"ID:{user[0]},姓名:{user[1]},年龄:{user[2]}")
            return user
        else:
            print(f"ID为 {user_id} 的用户不存在")
            return None
            
    finally:
        cursor.close()
        conn.close()

# 调用函数
user = get_user_by_id(1)

12. 修改用户年龄并确认修改生效

python

import pymysql

def update_user_age(user_id, new_age):
    """更新用户年龄"""
    conn = pymysql.connect(
        host='localhost',
        user='root',
        password='123456',
        database='test_db'
    )
    
    try:
        cursor = conn.cursor()
        
        # 更新数据
        sql = "UPDATE user SET age = %s WHERE id = %s"
        cursor.execute(sql, (new_age, user_id))
        
        # 提交事务
        conn.commit()
        
        # 通过rowcount确认修改生效
        if cursor.rowcount > 0:
            print(f"修改成功,影响了 {cursor.rowcount} 行数据")
            
            # 查询验证
            cursor.execute("SELECT id, name, age FROM user WHERE id = %s", (user_id,))
            user = cursor.fetchone()
            print(f"更新后数据:{user}")
            return True
        else:
            print("修改失败,可能没有找到对应的用户")
            return False
            
    except Exception as e:
        conn.rollback()
        print(f"更新失败:{e}")
        return False
        
    finally:
        cursor.close()
        conn.close()

# 调用函数
update_user_age(1, 22)

13. 删除用户记录的核心代码及注意事项

python

import pymysql

def delete_user_by_name(name):
    """根据姓名删除用户"""
    conn = pymysql.connect(
        host='localhost',
        user='root',
        password='123456',
        database='test_db'
    )
    
    try:
        cursor = conn.cursor()
        
        # 先查询确认要删除的数据
        cursor.execute("SELECT id, name FROM user WHERE name = %s", (name,))
        users_to_delete = cursor.fetchall()
        
        if users_to_delete:
            print(f"即将删除以下用户:")
            for user in users_to_delete:
                print(f"ID:{user[0]},姓名:{user[1]}")
            
            # 确认删除(实际应用中可能需要用户二次确认)
            confirm = input("确认删除?(y/n):")
            if confirm.lower() == 'y':
                # 执行删除
                sql = "DELETE FROM user WHERE name = %s"
                cursor.execute(sql, (name,))
                conn.commit()
                print(f"删除成功,共删除 {cursor.rowcount} 条记录")
            else:
                print("取消删除")
        else:
            print(f"没有找到姓名为 {name} 的用户")
            
    except Exception as e:
        conn.rollback()
        print(f"删除失败:{e}")
        
    finally:
        cursor.close()
        conn.close()

# 注意事项:
# 1. 删除前最好备份数据或先查询确认
# 2. 考虑外键约束
# 3. 建议添加软删除字段(is_deleted)替代物理删除
# 4. 批量删除时注意事务控制

14. 查询年龄在18到30之间的用户

python

import pymysql

def get_users_by_age_range():
    """查询年龄在18-30之间的用户"""
    conn = pymysql.connect(
        host='localhost',
        user='root',
        password='123456',
        database='test_db'
    )
    
    try:
        cursor = conn.cursor()
        
        # 查询SQL
        sql = "SELECT id, name, age FROM user WHERE age > %s AND age < %s"
        cursor.execute(sql, (18, 30))
        
        # 获取所有结果
        users = cursor.fetchall()
        
        if users:
            print(f"共找到 {len(users)} 条符合条件的数据:")
            for user in users:
                print(f"ID:{user[0]},姓名:{user[1]},年龄:{user[2]}")
        else:
            print("没有找到符合条件的数据")
            
        return users
        
    finally:
        cursor.close()
        conn.close()

# 调用函数
get_users_by_age_range()

15. 什么是游标?为什么必须创建游标?

游标(Cursor)

  • 数据库操作的一个指针或句柄

  • 用于执行SQL语句和管理查询结果

必须创建游标的原因

  • 执行SQL语句的入口

  • 管理查询结果集(逐行获取数据)

  • 控制事务边界

  • 获取受影响行数等信息

python

# 游标的作用示例
cursor = conn.cursor()  # 创建游标
cursor.execute(sql)      # 执行SQL
cursor.fetchone()        # 获取一行
cursor.fetchall()        # 获取所有行
cursor.rowcount          # 获取影响行数
cursor.lastrowid         # 获取最后插入ID
cursor.close()           # 关闭游标

16. fetchone()、fetchall()、fetchmany()的区别

python

import pymysql

conn = pymysql.connect(
    host='localhost',
    user='root',
    password='123456',
    database='test_db'
)

cursor = conn.cursor()
cursor.execute("SELECT id, name, age FROM user ORDER BY id")

# 1. fetchone() - 获取单条数据
print("===== fetchone() =====")
row1 = cursor.fetchone()
print(f"第一条:{row1}")  # 返回第一条数据

# 适合场景:查询单条记录,如根据ID查询用户详情

# 2. fetchmany(2) - 获取指定条数
print("===== fetchmany(2) =====")
rows2 = cursor.fetchmany(2)  # 获取接下来的2条
for row in rows2:
    print(row)

# 适合场景:分页查询,分批处理大量数据

# 3. fetchall() - 获取所有剩余数据
print("===== fetchall() =====")
all_rows = cursor.fetchall()  # 获取剩余所有数据
for row in all_rows:
    print(row)

# 适合场景:数据量较小,需要全部处理的情况

cursor.close()
conn.close()

三种方法的对比

方法 返回值 适用场景 内存占用
fetchone() 单条数据(元组) 单条查询、逐条处理
fetchmany(n) 列表(最多n条) 分批处理、分页 中等
fetchall() 列表(全部数据) 数据量小、需要全部数据

注意事项

  • 游标是单向的,只能向前获取数据

  • fetchall()在数据量大时可能占用大量内存

  • 使用fetchmany()可以平衡内存和性能

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐