浮头导航网

专注编程技术分享的开发者社区

Python数据库编程教程:第 9 章 数据库安全防护与异常处理

在数据库应用开发中,安全防护是避免数据泄露、篡改的关键(如防止 SQL 注入攻击、控制非法访问),而异常处理是保障应用稳定运行的基础(如应对数据库连接失败、SQL 语法错误)。本章基于python_db数据库,系统讲解 Python 数据库编程中的核心安全措施(SQL 注入防范、权限管理、数据加密)和全面的异常处理方案,通过规整案例和实操演示,帮助你构建安全、健壮的数据库应用。

9.1 数据库安全的核心威胁与防护原则

9.1.1 常见安全威胁

数据库应用面临的安全风险主要包括以下几类,需针对性防护:

威胁类型

核心危害

典型场景

SQL 注入攻击

非法执行 SQL 语句(如删表、窃取数据)

用户登录时输入' OR '1'='1,构造永真条件绕过验证,甚至执行DROP TABLE

权限滥用

未授权访问或修改数据(如普通用户删表)

应用使用 root 账号连接数据库,被攻击者利用后可操作所有表

数据泄露

敏感数据(如密码、手机号)被窃取

数据库备份文件未加密,或查询结果直接暴露敏感字段

连接信息泄露

数据库账号密码被窃取,导致非法连接

代码中硬编码数据库密码,或配置文件未加密存储

SQL 语法错误注入

通过输入特殊字符触发语法错误,暴露数据库信息

用户输入含'的字符串(如O'Neil),导致 SQL 语句语法错误,泄露表结构

9.1.2 安全防护核心原则

  1. 最小权限原则:应用使用的数据库账号仅授予必要权限(如仅SELECT/INSERT,不授予DROP/ALTER)。
  1. 参数化查询原则:所有用户输入均通过参数化方式传递,禁止直接拼接 SQL 字符串。
  1. 敏感数据加密原则:敏感字段(如密码)存储时需加密,避免明文存储。
  1. 异常信息隐藏原则:生产环境中不暴露原始数据库错误信息(如 SQL 语法错误详情),防止攻击者利用。

9.2 防范 SQL 注入攻击(核心安全措施)

SQL 注入是最常见且危害最大的数据库安全威胁,其本质是 “攻击者通过用户输入篡改 SQL 语句结构”。Python 中防范 SQL 注入的核心手段是参数化查询(使用%s占位符,而非字符串拼接),以下为详细演示。

9.2.1 SQL 注入攻击演示(危险写法)

先通过 “用户登录” 场景演示未防范 SQL 注入的危险:

import mysql.connector

from mysql.connector import Error

def unsafe_login(username, password):

"""未防范SQL注入的登录函数(危险!)"""

connection = None

try:

connection = mysql.connector.connect(

host='localhost',

user='root',

password='your_password',

database='python_db'

)

cursor = connection.cursor()

# 危险写法:直接拼接用户输入到SQL语句

unsafe_sql = f"SELECT * FROM users WHERE name = '{username}' AND password = '{password}'"

print(f"执行的SQL(危险,存在注入风险):{unsafe_sql}")

cursor.execute(unsafe_sql)

user = cursor.fetchone()

if user:

print(f"登录成功!欢迎您,{user[1]}")

else:

print("用户名或密码错误")

except Error as e:

print(f"登录出错:{e}")

finally:

if connection and connection.is_connected():

cursor.close()

connection.close()

# 正常测试:输入正确用户名和密码

print("=== 正常测试 ===")

unsafe_login(username="张三更新", password="123456") # 假设密码是123456(实际应加密)

# SQL注入测试:输入恶意字符串,绕过登录验证

print("\n=== SQL注入测试(危险)===")

# 输入密码为 "' OR '1'='1",拼接后SQL变为:

# SELECT * FROM users WHERE name = '任意用户名' AND password = '' OR '1'='1'

# '1'='1'是永真条件,将返回所有用户,实现非法登录

unsafe_login(username="任意用户名", password="' OR '1'='1")

运行结果(危险场景)

=== 正常测试 ===

执行的SQL(危险,存在注入风险):SELECT * FROM users WHERE name = '张三更新' AND password = '123456'

登录成功!欢迎您,张三更新

=== SQL注入测试(危险)===

执行的SQL(危险,存在注入风险):SELECT * FROM users WHERE name = '任意用户名' AND password = '' OR '1'='1'

登录成功!欢迎您,张三更新 # 未验证密码,直接登录成功,存在严重安全漏洞

9.2.2 防范 SQL 注入:参数化查询(安全写法)

使用%s作为占位符,将用户输入作为参数传递给execute()方法,禁止直接拼接字符串,可彻底防范 SQL 注入:

def safe_login(username, password):

"""防范SQL注入的登录函数(安全写法)"""

connection = None

try:

connection = mysql.connector.connect(

host='localhost',

user='root',

password='your_password',

database='python_db'

)

cursor = connection.cursor()

# 安全写法:使用%s占位符,用户输入作为参数传递

safe_sql = "SELECT * FROM users WHERE name = %s AND password = %s"

print(f"执行的SQL模板:{safe_sql}")

print(f"传递的参数:(username={username}, password={password})")

# 第二个参数必须是元组,即使只有一个参数也需加逗号

cursor.execute(safe_sql, (username, password))

user = cursor.fetchone()

if user:

print(f"登录成功!欢迎您,{user[1]}")

else:

print("用户名或密码错误")

except Error as e:

print(f"登录出错:{e}")

finally:

if connection and connection.is_connected():

cursor.close()

connection.close()

# 正常测试:正确用户名和密码

print("=== 正常测试 ===")

safe_login(username="张三更新", password="123456")

# SQL注入测试:输入恶意字符串(参数化查询会自动转义特殊字符,注入失效)

print("\n=== SQL注入测试(安全)===")

safe_login(username="任意用户名", password="' OR '1'='1")

运行结果(安全场景)

=== 正常测试 ===

执行的SQL模板:SELECT * FROM users WHERE name = %s AND password = %s

传递的参数:(username=张三更新, password=123456)

登录成功!欢迎您,张三更新

=== SQL注入测试(安全)==="

执行的SQL模板:SELECT * FROM users WHERE name = %s AND password = %s

传递的参数:(username=任意用户名, password=' OR '1'='1)

用户名或密码错误 # 注入失效,无法绕过验证,安全防护生效

原理说明

参数化查询中,MySQL 驱动会自动对用户输入的特殊字符(如'、;、OR)进行转义(如将'转换为\'),使恶意输入无法篡改 SQL 语句结构,从而彻底防范 SQL 注入。

9.3 数据库权限管理(最小权限原则)

默认的root账号拥有数据库的所有权限(如删库、改表),若应用使用root账号连接数据库,一旦被攻击,后果严重。正确做法是创建专用应用账号,仅授予必要权限(如SELECT/INSERT/UPDATE),遵循 “最小权限原则”。

9.3.1 创建应用专用账号(Python 实现)

以下示例创建一个名为app_user的账号,仅授予python_db数据库的SELECT、INSERT、UPDATE权限(无DELETE、DROP权限):

def create_app_user():

"""创建应用专用账号并授予最小权限"""

connection = None

try:

# 需使用root账号连接(只有root有权限创建新账号)

connection = mysql.connector.connect(

host='localhost',

user='root',

password='your_password',

database='python_db'

)

cursor = connection.cursor()

# 1. 创建账号(用户名:app_user,密码:App@123456,仅允许本地连接)

create_user_sql = "CREATE USER IF NOT EXISTS 'app_user'@'localhost' IDENTIFIED BY 'App@123456'"

cursor.execute(create_user_sql)

# 2. 授予权限:仅允许操作python_db数据库的SELECT/INSERT/UPDATE

grant_sql = """

GRANT SELECT, INSERT, UPDATE

ON python_db.* # 仅对python_db数据库的所有表生效

TO 'app_user'@'localhost'

"""

cursor.execute(grant_sql)

# 3. 撤销危险权限(确保无DROP/ALTER等权限)

revoke_sql = "REVOKE DROP, ALTER, DELETE ON python_db.* FROM 'app_user'@'localhost'"

cursor.execute(revoke_sql)

connection.commit()

print("应用专用账号'app_user'创建成功,已授予最小权限(SELECT/INSERT/UPDATE)")

# 验证权限

print("\n=== 验证app_user账号权限 ===")

cursor.execute("SHOW GRANTS FOR 'app_user'@'localhost'")

grants = cursor.fetchall()

for grant in grants:

print(grant[0])

except Error as e:

print(f"创建账号出错:{e}")

if connection:

connection.rollback()

finally:

if connection and connection.is_connected():

cursor.close()

connection.close()

if __name__ == "__main__":

create_app_user()

运行结果(规整对齐)

应用专用账号'app_user'创建成功,已授予最小权限(SELECT/INSERT/UPDATE)

=== 验证app_user账号权限 ===

GRANT USAGE ON *.* TO `app_user`@`localhost`

GRANT SELECT, INSERT, UPDATE ON `python_db`.* TO `app_user`@`localhost`

9.3.2 使用应用账号连接数据库(安全实践)

应用开发中,应使用app_user等专用账号连接数据库,而非root,即使账号泄露,攻击者也无法执行删表、改结构等危险操作:

def connect_with_app_user():

"""使用应用专用账号app_user连接数据库"""

connection = None

try:

# 使用app_user账号连接(仅拥有SELECT/INSERT/UPDATE权限)

connection = mysql.connector.connect(

host='localhost',

user='app_user', # 应用专用账号

password='App@123456', # 账号密码

database='python_db'

)

if connection.is_connected():

cursor = connection.cursor()

print("使用app_user账号连接数据库成功")

# 测试允许的操作(SELECT)

print("\n=== 测试允许的操作(SELECT)===")

cursor.execute("SELECT name, email FROM users LIMIT 2")

result = cursor.fetchall()

print("查询结果:")

for row in result:

print(row)

# 测试禁止的操作(DELETE,会报错)

print("\n=== 测试禁止的操作(DELETE)===")

cursor.execute("DELETE FROM users WHERE id = 1")

connection.commit()

except Error as e:

print(f"操作出错:{e}")

finally:

if connection and connection.is_connected():

cursor.close()

connection.close()

if __name__ == "__main__":

connect_with_app_user()

运行结果(权限控制生效)

使用app_user账号连接数据库成功

=== 测试允许的操作(SELECT)===

查询结果:

('张三更新', 'zhangsan@new-example.com')

('李四', 'lisi@new-example.com')

=== 测试禁止的操作(DELETE)===

操作出错:1142 (42000): DELETE command denied to user 'app_user'@'localhost' for table 'users'

结果分析

  • app_user账号可正常执行SELECT操作(允许的权限);
  • 执行DELETE操作时,MySQL 返回权限拒绝错误,说明最小权限原则生效,即使账号泄露,也无法删除数据。

9.4 敏感数据加密(密码加密存储)

用户密码等敏感数据若明文存储,一旦数据库泄露,攻击者可直接获取账号密码。正确做法是加密存储:将密码通过哈希算法(如 SHA-256)加盐(Salt)后存储,验证时比对哈希值而非明文。

9.4.1 密码加密存储实现(Python+hashlib)

使用hashlib库实现密码加盐哈希,示例如下:

import hashlib

import uuid # 用于生成随机盐值

def generate_salt():

"""生成随机盐值(16字节,确保每次加密结果不同)"""

return uuid.uuid4().hex # 生成32位随机字符串

def hash_password(password, salt):

"""密码加盐哈希:password + salt → SHA-256哈希"""

# 拼接密码和盐值,转换为UTF-8编码

password_salt = f"{password}{salt}".encode('utf-8')

# 使用SHA-256计算哈希值

hash_obj = hashlib.sha256(password_salt)

# 返回哈希值的十六进制字符串

return hash_obj.hexdigest()

def register_user(username, password):

"""用户注册:加密存储密码(含盐值)"""

connection = None

try:

connection = mysql.connector.connect(

host='localhost',

user='root',

password='your_password',

database='python_db'

)

# 先为users表新增salt和hashed_password字段(存储盐值和哈希后的密码)

cursor = connection.cursor()

cursor.execute("ALTER TABLE users ADD COLUMN salt VARCHAR(32), ADD COLUMN hashed_password VARCHAR(64)")

connection.commit()

# 生成盐值和哈希密码

salt = generate_salt()

hashed_pwd = hash_password(password, salt)

# 插入用户数据(存储盐值和哈希密码,不存储明文)

insert_sql = """

INSERT INTO users (name, email, salt, hashed_password)

VALUES (%s, %s, %s, %s)

"""

cursor.execute(insert_sql, (username, f"{username}@example.com", salt, hashed_pwd))

connection.commit()

print(f"用户'{username}'注册成功,密码已加密存储(盐值:{salt},哈希密码:{hashed_pwd[:20]}...)")

except Error as e:

if "Duplicate column name" in str(e):

# 字段已存在,直接插入数据

cursor = connection.cursor()

salt = generate_salt()

hashed_pwd = hash_password(password, salt)

insert_sql = "INSERT INTO users (name, email, salt, hashed_password) VALUES (%s, %s, %s, %s)"

cursor.execute(insert_sql, (username, f"{username}@example.com", salt, hashed_pwd))

connection.commit()

print(f"用户'{username}'注册成功,密码已加密存储(盐值:{salt},哈希密码:{hashed_pwd[:20]}...)")

else:

print(f"注册出错:{e}")

finally:

if connection and connection.is_connected():

cursor.close()

connection.close()

def login_with_encrypted_password(username, password):

"""用户登录:验证加密后的密码"""

connection = None

try:

connection = mysql.connector.connect(

host='localhost',

user='root',

password='your_password',

database='python_db'

)

cursor = connection.cursor()

# 查询用户的盐值和哈希密码

select_sql = "SELECT salt, hashed_password FROM users WHERE name = %s"

cursor.execute(select_sql, (username,))

user = cursor.fetchone()

if not user:

print("用户名不存在")

return

salt, stored_hash = user

# 使用相同的盐值对输入密码重新哈希</doubaocanvas>

9.4.1 密码加密存储实现(完整代码)

        input_hash = hash_password(password, salt)

# 比对输入密码的哈希值与存储的哈希值

if input_hash == stored_hash:

print(f"登录成功!欢迎您,{username}")

else:

print("用户名或密码错误")

except Error as e:

print(f"登录出错:{e}")

finally:

if connection and connection.is_connected():

cursor.close()

connection.close()

# 测试注册与加密登录

if __name__ == "__main__":

# 注册新用户(密码明文为"User@123",存储为哈希值)

print("=== 测试用户注册(密码加密存储)===")

register_user(username="安全测试用户", password="User@123")

# 测试正确密码登录

print("\n=== 测试正确密码登录 ===")


login_with_encrypted_password(username="安全测试用户", password="User@123")

# 测试错误密码登录

print("\n=== 测试错误密码登录 ===")


login_with_encrypted_password(username="安全测试用户", password="WrongPass123")

运行结果(规整对齐)

=== 测试用户注册(密码加密存储)===

用户'安全测试用户'注册成功,密码已加密存储(盐值:
a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6,哈希密码:
f8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c...)

=== 测试正确密码登录 ===

登录成功!欢迎您,安全测试用户

=== 测试错误密码登录 ===

用户名或密码错误

安全优势

  • 即使数据库泄露,攻击者获取的是salt(盐值)和hashed_password(哈希密码),无法通过哈希值反推明文密码;
  • 每个用户的盐值随机生成,即使两个用户密码相同,存储的哈希值也不同,避免 “彩虹表” 破解(一种通过预计算哈希值匹配密码的攻击方式)。

9.5 全面的异常处理机制

数据库操作过程中可能出现多种异常(如连接超时、SQL 语法错误、权限不足),若未处理,会导致应用崩溃或暴露敏感信息。Python 中需通过try-except-else-finally捕获异常,并分场景处理,同时在生产环境中隐藏原始错误详情。

9.5.1 常见数据库异常类型

MySQL 数据库操作中常见的异常及处理方式如下表所示:

异常类型(Error 代码)

异常描述

处理建议

示例场景

2003 (HY000)

无法连接数据库(如主机地址错误、服务未启动)

检查数据库服务状态、主机地址和端口

host='192.168.1.100'实际应为localhost

1045 (28000)

账号密码错误(Access denied)

验证数据库用户名和密码

password='12345'实际应为App@123456

1049 (42000)

数据库不存在(Unknown database)

检查数据库名称是否正确,或先创建数据库

database='python_db_test'实际应为python_db

1064 (42000)

SQL 语法错误(You have an error in your SQL syntax)

检查 SQL 语句语法(如关键字拼写错误、括号不匹配)

SELEC * FROM users(缺少T)

1142 (42000)

权限不足(如无 DELETE 权限)

验证数据库账号权限,或申请必要权限

app_user账号执行DELETE操作

2013 (HY000)

连接超时(Lost connection to MySQL server)

检查网络稳定性,或增加连接超时参数

远程数据库网络波动导致连接中断

9.5.2 分级异常处理实现(生产级)

以下示例实现分级异常处理:捕获特定异常并给出友好提示,未捕获的异常统一处理,同时在生产环境中隐藏原始错误信息:

import mysql.connector

from mysql.connector import Error

import logging

# 配置日志(生产环境中记录错误到日志文件,而非直接打印)

logging.basicConfig(

filename='db_error.log',

level=logging.ERROR,

format='%(asctime)s - %(levelname)s - %(message)s'

)

def safe_db_operation(sql, params=None, operation_type="read"):

"""

安全的数据库操作函数(支持读写操作,分级异常处理)

:param sql: SQL语句

:param params: SQL参数(元组,用于参数化查询)

:param operation_type: 操作类型(read:读操作,write:写操作)

:return: 查询结果(读操作)或影响行数(写操作),失败返回None

"""

connection = None

cursor = None

try:

# 1. 建立数据库连接(增加连接超时参数)

connection = mysql.connector.connect(

host='localhost',

user='app_user',

password='App@123456',

database='python_db',

connect_timeout=10 # 连接超时时间(10秒)

)

cursor = connection.cursor()

# 2. 执行SQL操作

cursor.execute(sql, params or ())

# 3. 区分读写操作,返回结果

if operation_type == "read":

result = cursor.fetchall()

logging.info(f"读操作成功,SQL:{sql},返回记录数:{len(result)}")

return result

else: # write操作(INSERT/UPDATE/DELETE)

connection.commit()

affected_rows = cursor.rowcount

logging.info(f"写操作成功,SQL:{sql},影响行数:{affected_rows}")

return affected_rows

except Error as e:

# 4. 分级处理特定异常

error_code = e.errno

error_msg = str(e)

# 记录原始错误到日志(生产环境排查用)

logging.error(f"数据库操作失败:SQL={sql},参数={params},错误代码={error_code},错误信息={error_msg}")

# 生产环境友好提示(隐藏敏感信息)

friendly_msg = "数据库操作失败,请稍后重试"

if error_code == 2003:

friendly_msg = "数据库服务暂时不可用,请检查服务状态"

elif error_code == 1045:

friendly_msg = "数据库认证失败,请联系管理员"

elif error_code == 1049:

friendly_msg = "目标数据库不存在,请确认配置"

elif error_code == 1064:

friendly_msg = "数据请求格式错误,请检查输入"

elif error_code == 1142:

friendly_msg = "当前操作权限不足,请联系管理员"

elif error_code == 2013:

friendly_msg = "数据库连接超时,请检查网络"

print(f"操作提示:{friendly_msg}")

# 写操作失败时回滚事务

if connection and operation_type == "write":

connection.rollback()

logging.warning("写操作失败,已执行事务回滚")

return None

except Exception as e:

# 5. 处理其他未捕获的异常(如代码逻辑错误)

unexpected_msg = f"意外错误:{str(e)}"

logging.error(unexpected_msg)

print("系统繁忙,请稍后重试")

return None

finally:

# 6. 确保资源释放(无论成功或失败,都关闭游标和连接)

if cursor:

cursor.close()

logging.debug("数据库游标已关闭")

if connection and connection.is_connected():

connection.close()

logging.debug("数据库连接已关闭")

# 测试分级异常处理

if __name__ == "__main__":

# 测试1:正常读操作(查询用户列表)

print("=== 测试1:正常读操作 ===")

select_sql = "SELECT name, email FROM users LIMIT 2"

result = safe_db_operation(sql=select_sql, operation_type="read")

if result:

print("查询结果:")

for row in result:

print(row)

# 测试2:权限不足异常(执行DELETE操作,app_user无权限)

print("\n=== 测试2:权限不足异常 ===")

delete_sql = "DELETE FROM users WHERE id = %s"

safe_db_operation(sql=delete_sql, params=(1,), operation_type="write")

# 测试3:SQL语法错误异常(SELEC拼写错误)

print("\n=== 测试3:SQL语法错误异常 ===")

wrong_sql = "SELEC name FROM users" # 错误:缺少T

safe_db_operation(sql=wrong_sql, operation_type="read")

运行结果(规整对齐)

=== 测试1:正常读操作 ===

查询结果:

('张三更新', 'zhangsan@new-example.com')

('李四', 'lisi@new-example.com')

=== 测试2:权限不足异常 ===

操作提示:当前操作权限不足,请联系管理员

=== 测试3:SQL语法错误异常 ===

操作提示:数据请求格式错误,请检查输入

日志文件(db_error.log)内容示例

2025-08-23 15:30:00,123 - INFO - 读操作成功,SQL:SELECT name, email FROM users LIMIT 2,返回记录数:2

2025-08-23 15:30:05,456 - ERROR - 数据库操作失败:SQL=DELETE FROM users WHERE id = %s,参数=(1,),错误代码=1142,错误信息=1142 (42000): DELETE command denied to user 'app_user'@'localhost' for table 'users'

2025-08-23 15:30:05,457 - WARNING - 写操作失败,已执行事务回滚

2025-08-23 15:30:10,789 - ERROR - 数据库操作失败:SQL=SELEC name FROM users,参数=(),错误代码=1064,错误信息=1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELEC name FROM users' at line 1

9.6 安全配置最佳实践

除上述措施外,还需通过以下配置进一步提升数据库安全性,避免常见安全漏洞:

9.6.1 避免硬编码连接信息

代码中硬编码数据库账号密码(如password='your_password'),若代码泄露,会直接导致连接信息泄露。正确做法是使用配置文件或环境变量存储连接信息,示例如下:

1. 使用配置文件(config.ini)存储连接信息

创建config.ini文件:

[mysql]

host = localhost

user = app_user

password = App@123456

database = python_db

port = 3306

connect_timeout = 10

2. Python 读取配置文件

import configparser

def get_db_config():

"""从配置文件读取数据库连接信息"""

config = configparser.ConfigParser()

config.read('config.ini') # 读取配置文件

return {

'host': config.get('mysql', 'host'),

'user': config.get('mysql', 'user'),

'password': config.get('mysql', 'user'),

'database': config.get('mysql', 'database'),

'port': int(config.get('mysql', 'port')),

'connect_timeout': int(config.get('mysql', 'connect_timeout'))

}

# 使用配置连接数据库

def connect_with_config():

connection = None

try:

db_config = get_db_config()

connection = mysql.connector.connect(**db_config)

print("使用配置文件连接数据库成功")

except Error as e:

print(f"连接出错:{e}")

finally:

if connection and connection.is_connected():

connection.close()

# 测试

connect_with_config()

安全注意事项

  • 配置文件需设置权限(如 Linux 下chmod 600 config.ini,仅所有者可读写);
  • 生产环境中,配置文件需通过加密工具加密(如cryptography库),避免明文存储。

9.6.2 限制数据库访问 IP

默认情况下,MySQL 允许所有 IP 连接(%通配符),存在远程攻击风险。正确做法是仅允许应用服务器 IP 访问数据库,示例如下:

-- 修改app_user账号,仅允许192.168.1.100(应用服务器IP)连接

UPDATE mysql.user SET Host = '192.168.1.100' WHERE User = 'app_user' AND Host = 'localhost';

FLUSH PRIVILEGES; -- 刷新权限

9.6.3 定期备份与日志审计

  1. 定期备份:通过第 6 章的备份方法,定期导出数据库数据(如每日凌晨备份),避免数据丢失;
  1. 日志审计:开启 MySQL 的查询日志和错误日志,记录所有数据库操作,便于事后排查安全事件:
# my.cnf(MySQL配置文件)中开启日志

general_log = 1

general_log_file = /var/log/mysql/mysql-general.log

log_error = /var/log/mysql/mysql-error.log

9.7 本章小结

本章系统讲解了 Python 数据库编程中的安全防护与异常处理核心技能:

  1. SQL 注入防范:通过参数化查询(%s占位符)彻底避免注入风险,禁止字符串拼接 SQL;
  1. 权限管理:创建应用专用账号,遵循最小权限原则,限制危险操作;
  1. 敏感数据加密:密码通过加盐哈希存储,避免明文泄露;
  1. 分级异常处理:捕获特定数据库异常,生产环境隐藏敏感错误信息,同时记录日志便于排查;
  1. 安全配置:使用配置文件存储连接信息、限制访问 IP、定期备份与审计。

下一章将学习 Python 数据库编程的高级应用 ——ORM 框架(如 SQLAlchemy),通过封装 SQL 操作,进一步简化数据库开发,提升代码可维护性。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言