为了使用pycouchdb
在CouchDB中的RPI上保存一些传感器数据,我创建了一个数据库模型类,使其具有清晰的结构,而不是松散类型的dict
class SensorMeasure(NamedTuple):
temp: float
soilMoisture: float
dateTime: datetime
因为似乎不可能自动序列化这个对象,所以我使用^{
server = pycouchdb.Server("http://127.0.0.1:5984/")
db = server.database(dbName)
measure = SensorMeasure(temp=sensor.getTemperature(), soilMoisture = sensor.getMoisture(), dateTime = datetime.now())
db.save(measure._asdict())
虽然这对诸如float之类的基本类型很有效,但它在datetime
上中断:
TypeError: Object of type datetime is not JSON serializable
似乎我必须tell the serializer how he could generate a string from the ^{
唯一的解决办法似乎是在SensorMeasure
模型中使用string
而不是datetime
,并使用datetime
的isoformat()
方法。但这需要我
就设计而言,最好在类中有一个datetime
属性。如何存档此文件
通过zip
函数,似乎可以定义应该序列化哪些键。这让我想到删除dateTime
字段,然后将其作为字符串值重新添加,如下所示:
class SensorMeasure(NamedTuple):
temp:float
soilMoisture: float
dateTime: datetime
def test(self):
serializeFields = list(self._fields)
del serializeFields['dateTime']
serialized = OrderedDict(zip(serializeFields, self))
print(serialized)
serialized['dateTime'] = dateTime.isoformat()
print(serialized)
但这不起作用,因为返回的元组是不可变的。将其转换为列表应该允许写入,但是列表似乎只允许整数键:
TypeError: list indices must be integers or slices, not str
可以定义自己的解码器/编码器。我这样做了,很好地保存了:
然后正常保存
可能还应该实现解码器,但这是非常明显的。我只在python端使用保存。您需要同时定义解码器和编码器,这就是为什么它不是空的
次优解决方法
这只是为了文档目的/完整性。向下滚动以获得更好的解决方案
通过一些转换操作,我的问题中的解决方案思想起了作用:
但这不仅仅是datetime序列化的大量代码/工作,这在每个模型中都是必需的。或者至少在每个模型中调用某个助手类
更好的解决方案:自定义
db.save
方法更好的解决方案是在
json.dumps
上设置默认解析方法不幸的是
pycouchdb
目前doesn't allow this。当然,我可以发送pull请求,例如通过一个新参数来扩展此功能。但现在,我只是创建了自己的save方法,作为一个快速且合适的修复方法唯一仍然存在的问题是使用
db.get()
时缺少键入:这将返回一个字典,因此仍然需要将字符串解析为datetime对象。这可以使用constructor来完成。不像我所知道的那么简单,例如从ASP.NET Core,序列化/反序列化可以用一行代码完成,但似乎是可能的
相关问题 更多 >
编程相关推荐