{"record":{"id":"5ca87b0efca87e9b","repo":"pathwaycom/pathway","slug":"primary-key-must-be-specified-for-the-snapshot-tab","errorCode":null,"errorMessage":"primary_key must be specified for the snapshot table type","messagePattern":"primary_key must be specified for the snapshot table type","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/duckdb/__init__.py","lineNumber":256,"sourceCode":"    Afterwards the embeddings can be searched with plain DuckDB SQL:\n\n    .. code-block:: sql\n\n        SELECT text, list_cosine_similarity(embedding, [1.0, 0.0, 0.0]) AS score\n        FROM documents\n        WHERE diff = 1\n        ORDER BY score DESC\n        LIMIT 5;\n    \"\"\"\n    _check_entitlements(\"duckdb\")\n\n    is_snapshot_mode = output_table_type == SNAPSHOT_OUTPUT_TABLE_TYPE\n    if not is_snapshot_mode and primary_key is not None:\n        raise ValueError(\n            \"primary_key can only be specified for the snapshot table type\"\n        )\n    if is_snapshot_mode and not primary_key:\n        raise ValueError(\"primary_key must be specified for the snapshot table type\")\n    if is_snapshot_mode and sort_by is not None:\n        # In snapshot mode an update is a deletion (-1) followed by an insertion\n        # (+1) of the same key. sort_by reorders the changes within a minibatch\n        # and can place the insertion before the deletion, so the upsert is\n        # immediately wiped by the delete — silently losing rows. sort_by has no\n        # effect on a snapshot's final (unordered, keyed) state anyway, so reject\n        # the combination instead of corrupting the output.\n        raise ValueError(\n            \"sort_by cannot be used with the snapshot table type: a snapshot \"\n            \"reflects the current state of the table regardless of the order \"\n            \"changes are applied within a minibatch, and reordering would corrupt \"\n            \"the upsert/delete sequence. Remove sort_by, or use \"\n            'output_table_type=\"stream_of_changes\".'\n        )\n\n    database_str = fspath(database)\n    _reject_directory_path(database_str)\n","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/duckdb/__init__.py#L238-L274","documentation":"Raised by pw.io.duckdb.write when output_table_type=\"snapshot\" is used without a primary_key. Snapshot mode maintains the current table state via keyed upserts/deletes, so it needs a key to identify rows; without one the connector cannot apply retractions correctly.","triggerScenarios":"pw.io.duckdb.write(table, table_name=\"t\", output_table_type=\"snapshot\") with no primary_key, or with primary_key=None (e.g. a conditional that evaluates to None).","commonSituations":"Switching a pipeline from stream_of_changes to snapshot and forgetting the key; primary_key passed conditionally (primary_key=pk if cond else None) where the None branch is hit.","solutions":["Supply a non-nullable column (or columns) as primary_key, e.g. pw.io.duckdb.write(t, table_name=\"t\", output_table_type=\"snapshot\", primary_key=t.id).","If no natural key exists, keep the default output_table_type=\"stream_of_changes\" which needs no key.","Ensure the key column is not declared Optional and is not a list/array/tuple/JSON column (those raise separate errors)."],"exampleFix":"# before\npw.io.duckdb.write(t, table_name=\"t\", output_table_type=\"snapshot\")\n\n# after\npw.io.duckdb.write(t, table_name=\"t\", output_table_type=\"snapshot\", primary_key=t.id)","handlingStrategy":"validation","validationCode":"if output_table_type == \"snapshot\" and not primary_key:\n    raise ValueError(\"snapshot output requires primary_key\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always define a natural non-nullable key column before adopting snapshot mode.","Guard conditional primary_key assignment: pk = pk if pk is not None else default_key."],"tags":["duckdb","connector","api-misuse"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}