使用moto模拟DynamoDB时filter_expression的between条件不生效问题
问题根因
你遇到的兼容性问题由两个已知原因导致:
- 你使用的
@mock_dynamodb2是moto已经废弃的旧版DynamoDB模拟实现,仅适配boto2的DynamoDB接口,和当前boto3使用的DynamoDB行为差异极大,其中就包含非主键属性between过滤条件的实现bug,会导致符合条件的记录无法正常返回。 - DynamoDB是类型敏感数据库,不同数据类型的比较会直接返回false。你之前分开写
gte(0) & lte(10)在生产返回空,大概率是生产环境存储的status字段类型和你查询时传入的参数类型不匹配,而旧版moto的类型校验逻辑宽松,会自动做隐式类型转换,所以本地测试可以通过。
最优解决方案
直接升级moto到3.0及以上版本,将测试代码中的@mock_dynamodb2替换为新版的@mock_dynamodb装饰器即可。
新版moto的DynamoDB模拟完全对齐AWS官方行为,between过滤条件已经修复,你可以统一在业务代码中使用Attr("status").between(0, 10)的写法,无需做任何环境兼容判断,本地测试和生产环境都可以正常返回结果。
无法升级moto的临时方案
如果受项目依赖限制暂时无法升级moto,可以按以下步骤处理:
- 先确认所有环境中
status字段存储的都是Number类型,插入数据时不要隐式转换为String类型 - 在测试用例的公共初始化部分添加猴子补丁修复moto的between过滤逻辑,不需要修改业务查询代码。
内容的提问来源于stack exchange,提问作者Nicolas
相关产品推荐
相关产品推荐

