{"record":{"id":"c953ff34bdd23191","repo":"YunaiV/ruoyi-vue-pro","slug":"col-type-name-ddl-table","errorCode":null,"errorMessage":"未支持的类型: '{col['type']}' (列: {name}, 表: {ddl['table_name']})","messagePattern":"未支持的类型: '(.+?)' \\(列: (.+?), 表: (.+?)\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"sql/tools/convertor.py","lineNumber":447,"sourceCode":"        if type in (\"blob\", \"mediumblob\", \"longblob\"):\n            return \"bytea\"\n        if type == \"decimal\":\n            return (\n                f\"numeric({','.join(str(s) for s in size)})\" if size and len(size) else \"numeric\"\n            )\n\n    def gen_create(self, ddl: Dict) -> str:\n        \"\"\"生成 create\"\"\"\n\n        def _generate_column(col):\n            name = col[\"name\"].lower()\n            if name == \"deleted\":\n                return \"deleted int2 NOT NULL DEFAULT 0\"\n\n            type = col[\"type\"].lower()\n            full_type = self.translate_type(type, col[\"size\"])\n            if full_type is None:\n                raise NotImplementedError(\n                    f\"未支持的类型: '{col['type']}' (列: {name}, 表: {ddl['table_name']})\"\n                )\n            nullable = \"NULL\" if col[\"nullable\"] else \"NOT NULL\"\n            default = f\"DEFAULT {col['default']}\" if col[\"default\"] is not None else \"\"\n            return f\"{self.escape_column_name(name)} {full_type} {nullable} {default}\"\n\n        table_name = ddl[\"table_name\"].lower()\n        columns = [f\"{_generate_column(col).strip()}\" for col in ddl[\"columns\"]]\n        filed_def_list = \",\\n  \".join(columns)\n        script = f\"\"\"-- ----------------------------\n-- Table structure for {table_name}\n-- ----------------------------\nDROP TABLE IF EXISTS {table_name};\nCREATE TABLE {table_name} (\n    {filed_def_list}\n);\"\"\"\n\n        return script","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/YunaiV/ruoyi-vue-pro/blob/0418084e222612af2fc1141f566af454f9236ab1/sql/tools/convertor.py#L429-L465","documentation":"Raised by _generate_column inside a convertor's gen_create when translate_type returns None for a MySQL column type it does not know how to map. translate_type is a fixed if/elif chain (e.g. varchar→varchar(size), int→int4, json→jsonb, blob→bytea); any type outside that chain (e.g. enum, set, mediumint, year, float, geometry, tinytext, char) yields None and this NotImplementedError fires, naming the offending column and table.","triggerScenarios":"Running the convertor (e.g. PostgreSQLConvertor) on a MySQL DDL that contains a column type absent from that convertor's translate_type chain. The error message embeds col['type'], the column name, and ddl['table_name'] so the exact column is identifiable.","commonSituations":"Source SQL includes MySQL-specific or rarely-used types (enum, set, year, mediumint, tinytext, mediumtext, geometry, point, char(n), float, real, numeric without size handling); a new schema migration adds an exotic type; using a target dialect whose convertor has a narrower type map than another convertor.","solutions":["Add a branch to the relevant convertor's translate_type returning the target-dialect equivalent (e.g. enum/set → text or varchar, year → int2, mediumint → int4).","Pre-scan the DDL for types not in the supported set and either rewrite the source column types or extend translate_type before converting.","If the column is disposable, drop or alter it in the source SQL before running the convertor.","Run the convertor dialect whose translate_type already covers your types (the PostgreSQL convertor at line 402 is one reference map)."],"exampleFix":"# before — translate_type has no branch for 'enum'\n#   → NotImplementedError: 未支持的类型: 'enum' (列: status, 表: t_order)\n\n# after — add a mapping\ndef translate_type(self, type, size):\n    type = type.lower()\n    ...\n    if type in (\"enum\", \"set\"):\n        return \"varchar\"\n    if type in (\"mediumint\", \"mediumint unsigned\"):\n        return \"int4\"\n    if type == \"year\":\n        return \"int2\"","handlingStrategy":"validation","validationCode":"# Pre-scan the DDL for types this convertor cannot map\nSUPPORTED = {\"varchar\",\"int\",\"int unsigned\",\"int unsigned zerofill\",\"bigint\",\"bigint unsigned\",\n    \"tinyint\",\"smallint\",\"tinyint unsigned\",\"datetime\",\"timestamp null\",\"date\",\"json\",\n    \"double\",\"timestamp\",\"bit\",\"text\",\"longtext\",\"blob\",\"mediumblob\",\"longblob\",\"decimal\"}\nfor ddl in ddls:\n    for col in ddl[\"columns\"]:\n        if col[\"name\"].lower() == \"deleted\":\n            continue\n        if col[\"type\"].lower() not in SUPPORTED:\n            raise SystemExit(f\"Unsupported type {col['type']} in {ddl['table_name']}.{col['name']} — extend translate_type first\")","typeGuard":"def is_type_supported(convertor, type_name: str, size) -> bool:\n    return convertor.translate_type(type_name.lower(), size) is not None","tryCatchPattern":null,"preventionTips":["Extend the convertor's translate_type with a branch for each MySQL type your schemas use.","Map open-ended MySQL types (enum/set/tinytext) to a safe target type like text/varchar.","Pre-scan source DDL against translate_type before running a large batch conversion.","If a type is genuinely unmappable, normalize it in the source SQL first."],"tags":["sql","convertor","ddl","type-mapping","postgres"],"backgroundTag":null,"analyzedSha":"0418084e222612af2fc1141f566af454f9236ab1","analyzedAt":"2026-08-14T00:56:18.412Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}