{"record":{"id":"f340e109c44f8226","repo":"risingwavelabs/risingwave","slug":"dynamodb-table-primary-key-must-match-risi","errorCode":null,"errorMessage":"DynamoDB table {} primary key {:?} must match RisingWave primary key {:?}","messagePattern":"DynamoDB table (.+?) primary key (.+?) must match RisingWave primary key (.+?)","errorType":"validation","errorClass":"SinkError::DynamoDb","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/dynamodb.rs","lineNumber":441,"sourceCode":"            table_name\n        )));\n    }\n\n    Ok(key_schema\n        .iter()\n        .map(|key_element| key_element.attribute_name().to_owned())\n        .collect())\n}\n\nfn validate_pk_matches_dynamodb_key_schema(\n    table_name: &str,\n    rw_pk_names: &[String],\n    dynamodb_keys: &[String],\n) -> Result<()> {\n    let rw_pk_set = rw_pk_names.iter().collect::<BTreeSet<_>>();\n    let dynamodb_key_set = dynamodb_keys.iter().collect::<BTreeSet<_>>();\n    if rw_pk_names.len() != dynamodb_keys.len() || rw_pk_set != dynamodb_key_set {\n        return Err(SinkError::DynamoDb(anyhow!(\n            \"DynamoDB table {} primary key {:?} must match RisingWave primary key {:?}\",\n            table_name,\n            dynamodb_keys,\n            rw_pk_names\n        )));\n    }\n\n    Ok(())\n}\n\nmod write_chunk_future {\n    use std::collections::HashMap;\n    use std::time::Duration;\n\n    use anyhow::anyhow;\n    use aws_sdk_dynamodb as dynamodb;\n    use aws_sdk_dynamodb::client::Client;\n    use dynamodb::types::{","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/dynamodb.rs#L423-L459","documentation":"The DynamoDB sink requires the RisingWave primary key columns to exactly match the target table's DynamoDB primary key (same count, same set of names, order-insensitive via BTreeSet). If they differ, writes would target wrong/partition keys, so validation fails with this message.","triggerScenarios":"CREATE SINK (or validation) where rw_pk_names != dynamodb_keys: e.g. RisingWave PK is (id) but the table key is (pk, sk), or column names differ in case/spelling (e.g. 'Id' vs 'id').","commonSituations":"Table pre-created with a composite key while the RisingWave relation has a single-column PK; key attribute names created with different casing; PK added to the RisingWave relation after the table was designed.","solutions":["Recreate the DynamoDB table with a key schema whose attribute names exactly match the RisingWave primary-key column names.","Alter the RisingWave relation (or a materialized view feeding the sink) so its primary key columns match the table's key attribute names and count.","Recreate the sink from a materialized view with a PK matching the table keys (e.g. make the MV's PK = (pk, sk)).","Check for case mismatches between column names and DynamoDB key attribute names."],"exampleFix":"// before: table key (pk, sk) but relation PK (id) -> mismatch\n// after: align the MV PK with the DynamoDB key\nCREATE MATERIALIZED VIEW mv AS SELECT pk, sk, payload FROM src WITH (PRIMARY KEY (pk, sk) NOT ENFORCED);\nCREATE SINK s FROM mv WITH (connector='dynamodb', table='events');","handlingStrategy":"validation","validationCode":"aws dynamodb describe-table --table-name events --query 'Table.KeySchema[].AttributeName'  # compare against the RisingWave relation's primary key column names","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Design the DynamoDB table key directly from the RisingWave relation's PK column names.","Watch for case differences between column names and key attribute names.","Use a materialized view with a matching PRIMARY KEY when the source PK doesn't fit the table keys.","Run sink validation in a staging environment before production."],"tags":["dynamodb","sink","primary-key","schema-mismatch","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}