YunaiV/yudao-cloud · error · NotImplementedError
f"未支持的类型: '{col['type']}' (列: {name}, 表: {ddl['table_name']}
Error message
f"未支持的类型: '{col['type']}' (列: {name}, 表: {ddl['table_name']})" What it means
Raised inside gen_create -> _generate_column in sql/tools/convertor.py when translate_type(type, size) returns None for the column's MySQL type. Each convertor's translate_type is a whitelist of if-comparisons (varchar, int, bigint, tinyint, datetime, json, double, bit, text, blob, decimal, ...); any MySQL type not on the list falls off the end, returning None, and _generate_column raises NotImplementedError naming the type, column, and table. It means the DDL convertor simply has no mapping rule for that column type yet.
Source
Thrown at sql/tools/convertor.py:447
if type in ("blob", "mediumblob", "longblob"):
return "bytea"
if type == "decimal":
return (
f"numeric({','.join(str(s) for s in size)})" if size and len(size) else "numeric"
)
def gen_create(self, ddl: Dict) -> str:
"""生成 create"""
def _generate_column(col):
name = col["name"].lower()
if name == "deleted":
return "deleted int2 NOT NULL DEFAULT 0"
type = col["type"].lower()
full_type = self.translate_type(type, col["size"])
if full_type is None:
raise NotImplementedError(
f"未支持的类型: '{col['type']}' (列: {name}, 表: {ddl['table_name']})"
)
nullable = "NULL" if col["nullable"] else "NOT NULL"
default = f"DEFAULT {col['default']}" if col["default"] is not None else ""
return f"{self.escape_column_name(name)} {full_type} {nullable} {default}"
table_name = ddl["table_name"].lower()
columns = [f"{_generate_column(col).strip()}" for col in ddl["columns"]]
filed_def_list = ",\n ".join(columns)
script = f"""-- ----------------------------
-- Table structure for {table_name}
-- ----------------------------
DROP TABLE IF EXISTS {table_name};
CREATE TABLE {table_name} (
{filed_def_list}
);"""
return scriptView on GitHub (pinned to 477be9dd49)
Solutions
- Read the message: it names the exact column type, column, and table — open the source DDL and confirm the raw type string (the code compares type.lower() against exact literals).
- Add a mapping branch to translate_type in the convertor class you are using (line 402 area for the PostgreSQL-family convertor) — e.g. `if type == "float": return "float4"`, `if type == "enum": return "varchar(255)"`, `if type == "char": return f"char({size})"`.
- If the type is irrelevant (audit/legacy column), strip or edit that column from the input SQL dump and re-run.
- For one-off conversions, pre-normalize the DDL with sed to rewrite the unsupported type to a supported one before feeding it to the convertor.
Example fix
# before — translate_type has no branch for 'float'/'enum', so it returns None and gen_create raises NotImplementedError
# after — add branches to translate_type (sql/tools/convertor.py, PostgreSQL-family convertor)
if type == "float":
return "float4"
if type == "enum":
return "varchar(255)"
if type == "char":
return f"char({size})" if size else "char" Defensive patterns
Strategy: type-guard
Validate before calling
SUPPORTED_TYPES = {
"varchar", "int", "int unsigned", "int unsigned zerofill", "bigint", "bigint unsigned",
"tinyint", "smallint", "tinyint unsigned", "datetime", "timestamp null", "date",
"json", "double", "timestamp", "bit", "text", "longtext", "blob", "mediumblob",
"longblob", "decimal",
}
# scan the parsed DDL before generating
def check_columns(ddl):
bad = [c for c in ddl["columns"] if c["type"].lower() not in SUPPORTED_TYPES and c["name"].lower() != "deleted"]
if bad:
raise ValueError(f"Unsupported types in table {ddl['table_name']}: {[(c['name'], c['type']) for c in bad]}") Type guard
def is_supported_type(col: Dict) -> bool:
"""True if convertor.translate_type maps this column type (never returns None)."""
if col["name"].lower() == "deleted":
return True
return convertor.translate_type(col["type"].lower(), col.get("size")) is not None Try / catch
try:
script = convertor.gen_create(ddl)
except NotImplementedError as e:
# e.message names the type, column, and table: add a mapping branch to
# translate_type, or normalize/skip that column, then re-run
log.warning("skipping table %s: %s", ddl["table_name"], e)
# decide: fix the mapping (preferred) or skip the table and report it Prevention
- Run a pre-flight scan of the DDL dump for column types before converting; flag anything outside the whitelist.
- Prefer plain types in source schemas (varchar over enum/set) when you control the schema.
- When adding a mapping, also add a unit DDL fixture so regressions in translate_type are caught.
- Keep a checklist of types each convertor subclass supports; they are not identical across targets.
When it happens
Trigger: Running the convertor CLI on a MySQL DDL dump that contains a column type not in the whitelist, e.g. ENUM('a','b'), SET, FLOAT, MEDIUMINT, CHAR(n), YEAR, GEOMETRY, VARBINARY, or a vendor-specific type. The error fires per-table while generating CREATE TABLE statements, and includes the offending column name and table name.
Common situations: Converting a hand-written or legacy schema that uses ENUM/SET instead of lookup tables; converting MySQL 8 dumps with newer types; a type spelled differently in the dump than the whitelist expects (the comparison is exact after .lower()); processing third-party application schemas (WordPress, etc.) with unusual types.
Related errors
AI-assisted analysis of YunaiV/yudao-cloud@477be9dd49 (2026-08-14).
Data as JSON: /api/errors/490b877415327b8a.
Report an issue: GitHub.