YunaiV/ruoyi-vue-pro · warning · NotImplementedError
不支持目标数据库类型: {args.type}
Error message
不支持目标数据库类型: {args.type} What it means
Raised by main() when argparse's args.type matches none of the if/elif branches mapping to a convertor class (postgres, oracle, sqlserver, dm8, kingbase, opengauss, highgo). In practice this is dead code under normal CLI use: the parser declares the same seven strings in its choices=[...] argument, so argparse exits with its own 'invalid choice' error (exit code 2) before main() ever reaches the else. The NotImplementedError only fires if the choices list and the elif chain drift out of sync, or if main() is invoked programmatically with an unguarded type.
Source
Thrown at sql/tools/convertor.py:1069
sql_file = pathlib.Path(args.path).resolve().as_posix()
convertor = None
if args.type == "postgres":
convertor = PostgreSQLConvertor(sql_file)
elif args.type == "oracle":
convertor = OracleConvertor(sql_file)
elif args.type == "sqlserver":
convertor = SQLServerConvertor(sql_file)
elif args.type == "dm8":
convertor = DM8Convertor(sql_file)
elif args.type == "kingbase":
convertor = KingbaseConvertor(sql_file)
elif args.type == "opengauss":
convertor = OpengaussConvertor(sql_file)
elif args.type == "highgo":
convertor = HighGoConvertor(sql_file)
else:
raise NotImplementedError(f"不支持目标数据库类型: {args.type}")
convertor.print()
if __name__ == "__main__":
main()
View on GitHub (pinned to 0418084e22)
Solutions
- Add the missing elif branch instantiating the new convertor class, mirroring the existing pattern.
- Keep argparse choices=[...] and the if/elif dispatch generated from a single source (e.g. a dict mapping type→convertor class) so they cannot drift.
- If invoking programmatically, validate the type against the known set before calling main().
- Use `python convertor.py -h` to list the supported types when unsure.
Example fix
# before
if args.type == "postgres":
convertor = PostgreSQLConvertor(sql_file)
elif args.type == "oracle":
...
else:
raise NotImplementedError(f"不支持目标数据库类型: {args.type}")
# after — single source of truth
CONVERTORS = {
"postgres": PostgreSQLConvertor,
"oracle": OracleConvertor,
"sqlserver": SQLServerConvertor,
"dm8": DM8Convertor,
"kingbase": KingbaseConvertor,
"opengauss": OpengaussConvertor,
"highgo": HighgoConvertor,
}
parser.add_argument("type", choices=list(CONVERTORS)) # argparse + dispatch share one map
...
convertor = CONVERTORS[args.type](sql_file) Defensive patterns
Strategy: validation
Validate before calling
# argparse already validates via choices=[...]; mirror it if calling main() directly
SUPPORTED_TYPES = {"postgres", "oracle", "sqlserver", "dm8", "kingbase", "opengauss", "highgo"}
if args.type not in SUPPORTED_TYPES:
raise SystemExit(f"unsupported type {args.type!r}; choose from {sorted(SUPPORTED_TYPES)}") Type guard
from typing import Literal DBType = Literal["postgres", "oracle", "sqlserver", "dm8", "kingbase", "opengauss", "highgo"]
Prevention
- Drive argparse choices and the dispatch chain from one dict so they cannot drift.
- Run `python convertor.py -h` to see the authoritative supported-type list.
- When importing main() programmatically, validate the type against the known set first.
- On adding a new dialect, update choices, the elif branch, and the Literal alias together.
When it happens
Trigger: Calling the script with a type not in {postgres, oracle, sqlserver, dm8, kingbase, opengauss, highgo} while bypassing argparse (e.g. importing main and calling it directly), OR after someone widens choices without adding the matching elif branch. Standard `python convertor.py <badtype>` never reaches here — argparse rejects it first.
Common situations: A maintainer adds a new dialect to choices but forgets the elif; a downstream script imports main() and passes args programmatically; refactoring that desynchronizes the choices list and the dispatch chain.
Related errors
AI-assisted analysis of YunaiV/ruoyi-vue-pro@0418084e22 (2026-08-14).
Data as JSON: /api/errors/c35716c6cb8619ce.
Report an issue: GitHub.