{"record":{"id":"8f199feda2547b68","repo":"pathwaycom/pathway","slug":"iceberg-reader-requires-explicit-primary-key-field","errorCode":null,"errorMessage":"Iceberg reader requires explicit primary key fields specification","messagePattern":"Iceberg reader requires explicit primary key fields specification","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/iceberg/__init__.py","lineNumber":189,"sourceCode":"    ...     name: str\n\n    Then, this table must be read from the Iceberg storage.\n\n    >>> input_table = pw.io.iceberg.read(\n    ...     catalog=pw.io.iceberg.RestCatalog(uri=\"http://localhost:8181/\"),\n    ...     namespace=[\"app\"],\n    ...     table_name=\"users\",\n    ...     schema=InputSchema,\n    ...     mode=\"static\",\n    ... )\n\n    Don't forget to run your program with ``pw.run`` once you define all necessary\n    computations. Note that you can also change the mode to ``\"streaming\"`` if you want\n    the changes in the table to be reflected in your computational pipeline.\n    \"\"\"\n\n    if schema.primary_key_columns() is None:\n        raise ValueError(\n            \"Iceberg reader requires explicit primary key fields specification\"\n        )\n\n    _check_entitlements(\"iceberg\")\n    schema, api_schema = read_schema(schema)\n\n    data_storage = api.DataStorage(\n        storage_type=\"iceberg\",\n        iceberg_catalog=catalog._to_engine(),\n        table_name=table_name,\n        namespace=namespace,\n        mode=internal_connector_mode(mode),\n    )\n    data_format = api.DataFormat(\n        format_type=\"transparent\",\n        **api_schema,\n    )\n","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/iceberg/__init__.py#L171-L207","documentation":"The Pathway Iceberg reader (pw.io.iceberg.read) requires the input schema to declare a primary key, because Iceberg tables are upsert/read by identifier and the connector needs to know which column(s) form the key. It raises ValueError when schema.primary_key_columns() returns None, i.e. no column was marked with primary_key=True.","triggerScenarios":"pw.io.iceberg.read(catalog=..., namespace=['app'], table_name='users', schema=InputSchema) where InputSchema is a pw.Schema class in which no column uses pw.column_definition(primary_key=True).","commonSituations":"Defining the schema as a plain class without primary_key annotations; porting a schema from csv/json connectors where primary keys are optional; assuming the Iceberg table's key metadata is enough and not mirroring it in the Pathway schema.","solutions":["Declare the primary key in the schema: class InputSchema(pw.Schema): user_id: str = pw.column_definition(primary_key=True).","For composite keys, mark every key column with primary_key=True.","Verify the chosen column(s) match the actual Iceberg table's identifier fields before running pw.run."],"exampleFix":"# before\nclass InputSchema(pw.Schema):\n    user_id: str\n    name: str\n# after\nclass InputSchema(pw.Schema):\n    user_id: str = pw.column_definition(primary_key=True)\n    name: str","handlingStrategy":"validation","validationCode":"if InputSchema.primary_key_columns() is None:\n    raise SystemExit(\n        \"Iceberg schema needs a primary_key=True column; \"\n        \"see https://pathway.com/developers/user-guide/io/iceberg/\"\n    )\n\npw.io.iceberg.read(catalog=catalog, table_name=\"users\", schema=InputSchema)","typeGuard":"def iceberg_ready(schema) -> bool:\n    return schema.primary_key_columns() is not None","tryCatchPattern":null,"preventionTips":["Always declare primary_key=True on the identifier column of Iceberg schemas.","Mirror the Iceberg table's identifier fields in the Pathway schema.","Add a startup assert on primary_key_columns() so misconfiguration fails before pw.run."],"tags":["iceberg","schema","primary-key","pathway"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}