To save some sensor data on a RPI in CouchDB using pycouchdb
, I created a database model class to have a clear structure instead of loosely typed dicts
class SensorMeasure(NamedTuple):
temp: float
soilMoisture: float
dateTime: datetime
Since it seems not possible to serialize this object automatically, I used the _asdict()
method from NamedTuple
to get an dict object, which could be stored in the database
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())
While this works well for primitive types like float, it breaks on datetime
:
TypeError: Object of type datetime is not JSON serializable
It seems like that I have to tell the serializer how he could generate a string from the datetime
object, which seems not possible for me without modifing pycouchdbs
source code.
The only working workaround seems using string
instead of datetime
in the SensorMeasure
model and use the isoformat()
method of datetime
. But this would require me to
- install additional libraries for parsing
- I have to parse it on every usage with the overhead of creating a new object, specify the format, ...
In terms of design, it would be much better to have a datetime
attribute in the class. How can I archive this?
Other workaround thoughts
With the zip
function it seems possible to define which keys should be serialized. This leads me to the idea of removing the dateTime
field and then re-adding it as string value like this:
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)
But this doesn't work since the returned tuple is immutable. Converting it to a list should allow writing, however the lists seems only allowing integer keys:
TypeError: list indices must be integers or slices, not str