{"record":{"id":"94f21aab31f8c01e","repo":"pathwaycom/pathway","slug":"primary-key-can-only-be-specified-for-the-snapshot","errorCode":null,"errorMessage":"primary_key can only be specified for the snapshot table type","messagePattern":"primary_key can only be specified for the snapshot table type","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/io/duckdb/__init__.py","lineNumber":252,"sourceCode":"    ...     init_mode=\"create_if_not_exists\",\n    ... )  # doctest: +SKIP\n    >>> pw.run()  # doctest: +SKIP\n\n    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        )","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/io/duckdb/__init__.py#L234-L270","documentation":"Raised by pw.io.duckdb.write when a `primary_key` argument is supplied while `output_table_type` is not \"snapshot\" (i.e. the default stream_of_changes mode). A primary key only makes sense for an upsert-style snapshot table; the change-stream output appends time/diff metadata rows and has no keyed state.","triggerScenarios":"pw.io.duckdb.write(table, table_name=\"t\", primary_key=table.some_col) — primary_key given but output_table_type left at its default, or explicitly set to \"stream_of_changes\".","commonSituations":"Upgrading or copying code from other connectors (e.g. pw.io.postgres) where primary_key is accepted for deduplication; assuming snapshot semantics without reading the default output_table_type.","solutions":["Set output_table_type=\"snapshot\" so primary_key drives the upsert behavior: pw.io.duckdb.write(t, table_name=\"t\", output_table_type=\"snapshot\", primary_key=t.id).","Or drop the primary_key argument if you actually want an append-only stream of changes with time/diff columns."],"exampleFix":"# before\npw.io.duckdb.write(t, table_name=\"t\", primary_key=t.id)\n\n# after\npw.io.duckdb.write(t, table_name=\"t\", output_table_type=\"snapshot\", primary_key=t.id)","handlingStrategy":"validation","validationCode":"if primary_key is not None and output_table_type != \"snapshot\":\n    raise ValueError(\"primary_key requires output_table_type='snapshot'\")","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat primary_key and output_table_type as one coupled config unit; set or clear both together.","Centralize duckdb write config in one dataclass so the combination is validated once."],"tags":["duckdb","connector","api-misuse"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}