{"record":{"id":"530a3a94eb309e44","repo":"cocoindex-io/cocoindex","slug":"pk-column-pk-not-in-columns-list-self-column","errorCode":null,"errorMessage":"PK column '{pk}' not in columns: {list(self.columns.keys())}","messagePattern":"PK column '(.+?)' not in columns: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/doris/_target.py","lineNumber":356,"sourceCode":"@dataclass(slots=True)\nclass TableSchema(Generic[RowT]):\n    columns: dict[str, ColumnDef]\n    primary_key: list[str]\n    row_type: type[RowT] | None\n\n    def __init__(\n        self,\n        columns: dict[str, ColumnDef],\n        primary_key: list[str],\n        *,\n        row_type: type[RowT] | None = None,\n    ) -> None:\n        self.columns = columns\n        self.primary_key = primary_key\n        self.row_type = row_type\n        for pk in self.primary_key:\n            if pk not in self.columns:\n                raise ValueError(\n                    f\"PK column '{pk}' not in columns: {list(self.columns.keys())}\"\n                )\n\n    @classmethod\n    async def from_class(\n        cls,\n        record_type: type[RowT],\n        primary_key: list[str],\n        *,\n        column_overrides: dict[str, DorisType | res_schema.VectorSchemaProvider]\n        | None = None,\n    ) -> \"TableSchema[RowT]\":\n        if not is_record_type(record_type):\n            raise TypeError(\n                f\"record_type must be a record type, got {type(record_type)}\"\n            )\n        columns = await cls._columns_from_record_type(record_type, column_overrides)\n        return cls(columns, primary_key, row_type=record_type)","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/doris/_target.py#L338-L374","documentation":"TableSchema validates that every column listed in primary_key exists among the derived columns. When a PK name does not match any record field (after column name derivation and overrides), the schema is unusable for DDL/loads, so __init__ fails fast with ValueError.","triggerScenarios":"Calling TableSchema(columns, primary_key=[...]) directly or from_class(..., primary_key=['id']) where 'id' is not a field name of the record type (typo, different casing, or the field was renamed/excluded by overrides).","commonSituations":"Renaming a dataclass field without updating primary_key; specifying the Python attribute name while the column name was overridden; passing key column names from an old schema version.","solutions":["Correct the primary_key list to use exact column names present in the record type","If the PK field has a column name override, use the overridden column name in primary_key","Add the missing field to the record type or remove it from primary_key"],"exampleFix":"// before\nTableSchema.from_class(Record, primary_key=[\"doc_id\"])\nclass Record: id: int\n// after\nTableSchema.from_class(Record, primary_key=[\"id\"])","handlingStrategy":"validation","validationCode":"cols = {f.name for f in dataclasses.fields(MyRecord)}\nassert set(primary_key) <= cols, f\"unknown PKs: {set(primary_key) - cols}\"","typeGuard":null,"tryCatchPattern":"try:\n    schema = TableSchema(columns, primary_key)\nexcept ValueError as e:\n    logger.error(\"PK mismatch: %s\", e); raise","preventionTips":["Keep primary_key names in sync with record field names","Use the overridden column name, not the Python attribute name","Validate PK names against the record type in tests"],"tags":["doris","schema","primary-key","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}