boto3: Parameter validation failed (ParamValidationError)

TL;DR — botocore.exceptions.ParamValidationError在你的机器上、在任何请求被发送之前抛出的——你传入的参数与操作期望的形态不匹配。在 DynamoDB 代码中,它几乎总是一个 client 与 resource 的混淆:底层 client 想要 DynamoDB-JSON({'S': 'abc'},数字作为字符串),而 Table resource 想要原生 Python 类型。让类型风格与你调用的接口相匹配。

含义

botocore.exceptions.ParamValidationError: Parameter validation failed:
Invalid type for parameter Item.price.N, value: 42, type: <class 'int'>,
valid types: <class 'str'>

botocore 在签名之前会根据服务的 API 模型验证每一次调用。这里的失败不是一个 ClientError——DynamoDB 从未看到该请求——因此 except ClientError 不会捕获它,也没有发生网络往返。消息会指明失败的确切参数路径及其期望的类型。

为什么会发生

  • 把原生 Python 值传给了底层 client——boto3.client('dynamodb') 说的是原始 DynamoDB JSON:每个属性都是一个带类型标记的 map,且 N 值是_字符串_({'N': '42'},而不是 42)。
  • 把 DynamoDB-JSON 传给了 Table resource——相反的混淆:boto3.resource('dynamodb').Table(...) 期望纯 Python 值,并为你做 marshal。
  • 在期望字符串的地方用了 Condition 对象——查询分页器的 KeyConditionExpression 接受一个字符串表达式;Key('pk').eq(...) 对象在那里会验证失败。
  • 一个拼错或不受支持的参数名——未知的键会验证失败;一个过时的 botocore 也可能拒绝在其捆绑模型之后才加入 API 的参数。

如何修复

  1. 选定一个接口并一致地使用它的类型风格:

    # Table resource — native Python types
    table = boto3.resource('dynamodb').Table('orders')
    table.put_item(Item={'pk': 'ORDER#1', 'price': Decimal('42')})
    
    # Low-level client — DynamoDB-JSON, numbers as strings
    client = boto3.client('dynamodb')
    client.put_item(TableName='orders',
                    Item={'pk': {'S': 'ORDER#1'}, 'price': {'N': '42'}})
  2. 对分页器使用字符串表达式——KeyConditionExpression='pk = :p'ExpressionAttributeValues,或者用 LastEvaluatedKey 手动对 Table resource 分页。

  3. 读消息中的参数路径——Item.price.N 准确告诉你是哪个属性、哪个类型标记失败了;修复那一个字段,而不是猜测。

  4. 对 "Unknown parameter" 失败升级 botocore——如果参数是真实的但你的验证模型早于它,pip install -U boto3 botocore

  5. 把它与服务错误分开捕获:

    from botocore.exceptions import ClientError, ParamValidationError
    try:
        client.put_item(**kwargs)
    except ParamValidationError as e:   # local: fix the call
        ...
    except ClientError as e:            # remote: DynamoDB rejected it
        ...

手写 DynamoDB-JSON 正是这些类型标记出错之处——DynamoDB JSON 转换器在原生 JSON 与带类型标记的传输格式之间转换,而 DynoTable 桌面应用编辑项目时会为你处理好 marshal。

相关错误

References

最后核实于 2026-07-13,依据上方链接的 AWS 官方文档。

无需控制台即可使用 DynamoDB

DynoTable 是面向 DynamoDB 的快速桌面客户端 —— 浏览表、运行 SQL 风格的查询,并在本地编辑项。