You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python MySQL自动化脚本报错求助:-o未识别及NameError问题

问题分析与修复方案

我帮你拆解下遇到的两个错误,然后给出完整的修复方案:

错误根源解析

  1. option -o not recognized:你的脚本里getopt的短选项定义是"hd:s:",这只注册了-h、-d、-s三个选项,但你实际调用时用的是-o、-dp、-dr,完全不匹配,所以系统识别不了-o。
  2. NameError: name 'opts' is not defined:当getopt解析参数出错时,会进入except块打印错误,但此时try块里的opts, args = ...根本没执行成功,opts变量压根没被创建,后面的代码自然找不到它。

另外还有个隐藏问题:你的脚本没导入getopt模块,这也是运行时会报错的坑。

修复后的完整代码

我把所有问题都修复了,还优化了SQL模板和参数校验,关键修改点都标出来了:

from sys import argv
from os import makedirs, system
import getopt  # 补上缺失的getopt导入

etc = '/mnt/storage/'

def show_usage():
    print("""Usage: Create new DB and DB user
Options:
  -o, --object_name    填写要创建的数据库/用户名
  -p, --db_password    设置数据库用户的密码
  -r, --root_password  提供MySQL root账户的密码
Example: python create_db.py -o test -p papa -r nana""")
    exit(1)

def create_template(object_name, password):
    # 替换成真实的创建DB和用户的SQL语句,你可以按需调整权限
    out = f"""CREATE DATABASE IF NOT EXISTS `{object_name}`;
CREATE USER IF NOT EXISTS `{object_name}`@'localhost' IDENTIFIED BY '{password}';
GRANT ALL PRIVILEGES ON `{object_name}`.* TO `{object_name}`@'localhost';
FLUSH PRIVILEGES;"""
    return out

def write_to_sql(object_name, db_password):
    sql_path = etc + 'new_db_and_user.sql'
    # 用with语句更安全,自动关闭文件
    with open(sql_path, 'w+') as sql_script:
        script_to_write = create_template(object_name, db_password)
        sql_script.write(script_to_write)
    return sql_path

def execute_sql_script(root_password, sql_path):
    # 用绝对路径执行脚本,避免mysql找不到文件
    run_sql_script = f"mysql --username=root --password={root_password} < {sql_path}"
    remove_sql_script = f"rm -f {sql_path}"
    system(run_sql_script)
    system(remove_sql_script)

try:
    # 关键修改:正确定义短选项和长选项映射
    opts, args = getopt.getopt(argv[1:], "ho:p:r:", [
        "object_name=",
        "db_password=",
        "root_password="
    ])
except getopt.GetoptError as err:
    print(str(err))
    show_usage()  # 出错后直接显示用法并退出,避免后续代码报错

# 初始化参数变量
object_name = None
db_password = None
root_password = None

for option, value in opts:
    if option in ('-o', '--object_name'):
        object_name = value
    elif option in ('-p', '--db_password'):
        db_password = value
    elif option in ('-r', '--root_password'):
        root_password = value
    elif option == '-h':
        show_usage()
    else:
        print("Unknown parameter used")
        show_usage()

# 校验必要参数是否齐全
if not all([object_name, db_password, root_password]):
    print("Error: 缺少必要参数!")
    show_usage()

# 执行创建流程
sql_file_path = write_to_sql(object_name, db_password)
execute_sql_script(root_password, sql_file_path)

关键修改说明

  1. 规范getopt选项:改成"ho:p:r:"对应-o、-p、-r短选项,同时绑定长选项,符合getopt的使用规范(getopt短选项是单个字符,-dp这种多字符会被解析错误,所以换成-p更合理)。
  2. 异常处理优化:解析出错后直接调用show_usage()退出,避免后续代码访问未定义的opts。
  3. 参数校验:确保三个必填参数都被提供,防止空值导致SQL执行失败。
  4. SQL模板优化:替换成真实的数据库/用户创建语句,原模板是占位符,无法实际执行。
  5. 文件路径统一:用绝对路径读写SQL脚本,避免mysql找不到文件。

测试命令

修复后用这个命令测试:

python create_db.py -o test -p papa -r nana

如果你坚持想用原命令的-dp、-dr参数,可以改用长选项调用:

python create_db.py -o test --db_password papa --root_password nana

内容的提问来源于stack exchange,提问作者mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 11:32:54