使用python新建表
完成MySQL实验,安装MySQLServer、MySQL Workbench。在Pyhon中设计代码,完成新建一个数据库mydb、新建一个student表。完成后给出MySQL Workbench的截图
安装MySQLServer、MySQL Workbench
安装完成后的截图:
python代码
import mysql.connector
from mysql.connector import errorcode
import logging
# 配置日志记录
logging.basicConfig(
level=logging.INFO, # 设置日志级别为INFO,可以根据需要调整为DEBUG等
format="%(asctime)s - %(levelname)s - %(message)s", # 设置日志输出格式
handlers=[
logging.StreamHandler() # 输出到控制台
# logging.FileHandler("mysql_operations.log") # 如果需要输出到文件,可以添加此行
],
)
# 数据库连接配置
# 建议将此配置移至外部配置文件,以避免硬编码敏感信息和提高灵活性。
# 例如,可以使用 configparser 或 os.environ 来读取配置。
# 当前为简化示例,仍保留在此处,但请注意生产环境中应避免硬编码密码。
DB_CONFIG = {
"host": "200.1.17.17",
"user": "root",
"password": "mysql_hwDTeQ",
"port": 3306,
}
# 数据库名称和表名称
# 建议将这些常量作为参数传递给相关函数,而不是使用全局变量,以提高函数的独立性和可重用性。
DATABASE_NAME = "mydb"
TABLE_NAME = "student"
def create_database(cursor, db_name):
"""创建数据库
此函数用于在MySQL服务器上创建一个新的数据库。
它首先尝试执行CREATE DATABASE语句。如果数据库已存在,则捕获特定的MySQL错误并打印提示信息。
如果发生其他MySQL错误,则打印详细的错误信息。
Args:
cursor: MySQL数据库游标对象,用于执行SQL命令。
db_name: 要创建的数据库的名称 (字符串)。
Raises:
mysql.connector.Error: 如果执行SQL语句时发生除数据库已存在以外的错误。
"""
try:
# 怎么做的: 执行SQL命令创建数据库
# 为什么这么做: 确保后续操作所需的数据库存在
cursor.execute(f"CREATE DATABASE {db_name} DEFAULT CHARACTER SET 'utf8mb4'")
logging.info(f"数据库 '{db_name}' 创建成功!")
except mysql.connector.Error as err:
# 怎么做的: 捕获MySQL错误
# 为什么这么做: 根据错误类型进行不同的处理,避免程序崩溃
if err.errno == errorcode.ER_DB_CREATE_EXISTS:
logging.info(f"数据库 '{db_name}' 已存在。")
else:
logging.error(f"创建数据库失败: {err}")
# 对于更详细的错误,可以打印 err.msg
# logging.error(f"错误详情: {err.msg}")
raise err # 重新抛出异常,让调用者知道发生了错误
def create_table(cursor, db_name, table_name):
"""创建表
此函数用于在指定的数据库中创建一个新的表。
它首先尝试执行CREATE TABLE语句。如果表已存在,则捕获特定的MySQL错误并打印提示信息。
如果发生其他MySQL错误,则打印详细的错误信息。
Args:
cursor: MySQL数据库游标对象,用于执行SQL命令。
db_name: 表所属的数据库名称 (字符串)。
table_name: 要创建的表的名称 (字符串)。
Raises:
mysql.connector.Error: 如果执行SQL语句时发生除表已存在以外的错误。
"""
# SQL 创建表的语句
# 怎么做的: 定义创建表的SQL语句
# 为什么这么做: 描述表的结构和属性
table_description = f"""
CREATE TABLE {table_name} (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
age INT,
major VARCHAR(255),
enrollment_date DATE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
"""
try:
logging.info(f"正在创建表 '{table_name}'...")
# 怎么做的: 执行SQL命令创建表
# 为什么这么做: 在数据库中建立数据存储结构
cursor.execute(f"USE {db_name}") # 切换到目标数据库
cursor.execute(table_description)
logging.info(f"表 '{table_name}' 创建成功!")
except mysql.connector.Error as err:
# 怎么做的: 捕获MySQL错误
# 为什么这么做: 根据错误类型进行不同的处理,避免程序崩溃
if err.errno == errorcode.ER_TABLE_EXISTS_ERROR:
logging.info(f"表 '{table_name}' 已存在。")
else:
logging.error(f"创建表失败: {err}")
# 对于更详细的错误,可以打印 err.msg
# logging.error(f"错误详情: {err.msg}")
raise err # 重新抛出异常
def main():
"""主函数
此函数是程序的入口点,负责建立数据库连接,调用创建数据库和表的函数,并处理连接过程中的错误。
它使用try...except...finally块来确保数据库连接和游标在程序结束时被正确关闭,即使发生错误。
怎么做的: 尝试连接数据库,调用创建函数,提交事务,并在发生错误或程序结束时关闭资源。
为什么这么做: 组织程序的执行流程,管理数据库连接生命周期,并提供基本的错误处理。
"""
conn = None
cursor = None
try:
# 连接到MySQL服务器(不指定数据库,因为要先创建数据库)
# 怎么做的: 使用DB_CONFIG字典中的参数建立数据库连接
# 为什么这么做: 连接到MySQL服务器以便执行后续的数据库操作
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor()
# 1. 创建数据库
# 怎么做的: 调用create_database函数创建数据库
# 为什么这么做: 确保目标数据库存在
create_database(cursor, DATABASE_NAME)
# 在创建表之前,需要先选择或连接到 mydb 数据库
# 如果数据库是刚刚创建的,则需要重新连接或使用 USE 语句
# 怎么做的: 调用create_table函数创建表
# 为什么这么做: 在已存在的数据库中创建所需的数据表结构
create_table(cursor, DATABASE_NAME, TABLE_NAME)
# 提交事务
# 怎么做的: 提交所有挂起的数据库操作
# 为什么这么做: 确保数据库的更改被永久保存
conn.commit()
logging.info("事务已提交。")
except mysql.connector.Error as err:
# 怎么做的: 捕获MySQL连接或操作过程中发生的错误
# 为什么这么做: 根据错误类型提供用户友好的错误信息,并记录详细错误以便调试
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
logging.error("连接失败: 用户名或密码错误。")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
logging.error("连接失败: 数据库不存在。")
else:
logging.error(f"连接数据库或执行操作时发生未知错误: {err}")
# logging.error(f"错误详情: {err.msg}")
except Exception as e:
# 怎么做的: 捕获其他可能的异常
# 为什么这么做: 提供一个通用的错误捕获,防止程序因未预料的错误而崩溃
logging.error(f"发生未预料的错误: {e}")
finally:
# 怎么做的: 无论是否发生错误,都尝试关闭游标和连接
# 为什么这么做: 释放数据库资源,避免资源泄露
if cursor:
cursor.close()
logging.info("数据库游标已关闭。")
if conn:
conn.close()
logging.info("数据库连接已关闭。")
# 进一步优化建议:
# 1. 配置管理:将数据库连接配置移至外部文件 (如 .ini, .env) 或环境变量。
# 2. 错误处理:考虑使用自定义错误码或更结构化的错误处理方式,而不是仅依赖异常捕获。
# 3. 连接池:对于频繁的数据库操作,考虑使用连接池来提高性能和资源利用率。
# 4. 上下文管理器:为数据库连接和游标创建上下文管理器 (使用 'with' 语句),可以简化资源管理。
# 5. 单元测试:为数据库操作函数编写单元测试,确保其功能正确性。
# 6. 代码规范:使用如 Black, Flake8 等工具进行代码格式化和规范检查。
if __name__ == "__main__":
main()