为何PynamoDB查询本地二级索引时未投影主表属性?
问题分析与解决方案
核心问题
使用PynamoDB的Local Secondary Index(LSI)并设置AllProjection()后,查询返回的模型实例中,父类定义的created、updated、heartbeat属性值为Null,不符合预期。
可能原因与对应解决方案
1. PynamoDB库反序列化依赖索引类的属性声明
尽管AWS官方文档明确LSI的AllProjection会包含主表所有属性,但PynamoDB Python库在反序列化查询结果时,需要索引类中显式声明对应的非键属性,才能正确将返回值映射到模型实例的属性上。
解决方案:在Id2Index类中添加与主表一致的属性声明:
class Id2Index(LocalSecondaryIndex): class Meta: projection = AllProjection() kind = UnicodeAttribute(hash_key=True) id2 = UnicodeAttribute(range_key=True) # 添加需要获取的非键属性声明,与主表定义一致 created = JavaDateTimeAttribute() updated = JavaDateTimeAttribute() heartbeat = JavaDateTimeAttribute()
2. 查询使用的模型类与数据实际类型不匹配
你通过父类Resource的索引查询,但数据是由子类Job写入的。使用父类索引查询返回的是Resource实例,可能存在属性映射偏差。
解决方案:改用子类Job的索引进行查询,确保实例类型与数据匹配:
r = Job.id2_index.query('job', Job.id2 > self.last_job_key)
3. 验证投影配置与数据存储正确性
- 登录AWS控制台,检查该LSI的投影类型是否确实为
ALL,确认PynamoDB服务端的索引配置无误。 - 直接查询主表的目标记录,验证
created等属性是否已正确存储(排除数据写入时的问题):job = Job.get('job', target_id) print(job.created) # 确认该值不为Null
4. 检查JavaDateTimeAttribute的序列化/反序列化
确保JavaDateTimeAttribute在写入时生成了符合格式的时间戳,且查询时能正确解析。可以尝试将属性临时替换为UnicodeAttribute测试,若能正常获取值,则说明是时间类型的反序列化问题,需检查JavaDateTimeAttribute的配置。
内容的提问来源于stack exchange,提问作者CryptoFool
相关产品推荐
相关产品推荐

