为了使用pycouchdb
在CouchDB中的RPI上保存一些传感器数据,我创建了一个数据库模型类,使其具有清晰的结构,而不是松散类型的字典
class SensorMeasure(NamedTuple):
temp: float
soilMoisture: float
dateTime: datetime
由于似乎不可能自动序列化该对象,因此我使用_asdict()
method from NamedTuple
来获取一个dict对象,该对象可以存储在数据库中
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 datetime
object,这似乎是不可能的,我没有修改pycouchdbs
源代码。
唯一可行的解决方法似乎是在SensorMeasure
模型中使用string
而不是datetime
,并使用datetime
的isoformat()
方法。
- install additional libraries for parsing
1.我必须在每次使用时解析它,开销包括创建新对象、指定格式...
在设计方面,类中有一个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
2条答案
按热度按时间guz6ccqo1#
次优解决方案
这只是为了说明文档/完整性。向下滚动以获得更好的解决方案
通过几个转换操作,我的问题中的解决方案想法奏效了:
但是,这不仅仅是每个模型都需要的日期时间序列化的大量代码/工作,或者至少是每个模型中对某个帮助器类的调用。
更好的解决方案:自定义
db.save
方法更好的解决方案是在
json.dumps
上设置默认解析方法遗憾的是
pycouchdb
目前不允许这样做。当然我可以发送pull请求,通过一个新的参数来扩展这个功能。但是现在,我只是创建我自己的保存方法作为一个快速和合适的修复。唯一仍然存在的问题是使用
db.get()
时缺少类型:这将返回一个字典,因此仍然需要将字符串解析为一个日期时间对象。可以使用constructor来完成。这并不像我所知道的那样容易,例如在ASP.NET核心中,串行化/反串行化可以用一行代码完成,但似乎是可能的。
svujldwt2#
可以定义您自己的解码器/编码器。我这样做了,工作正常保存:
然后正常执行保存。
可能还应该实现解码器,但这是很明显的。我只在python端使用保存。你需要定义解码器和编码器,这就是为什么它不是空的。