Чтобы сохранить некоторые данные датчиков в RPI в CouchDB с использованием pycouchdb
, я создал класс модели базы данных, чтобы иметь четкую структуру вместо слабо типизированных dicts
class SensorMeasure(NamedTuple):
temp: float
soilMoisture: float
dateTime: datetime
Поскольку кажется невозможным сериализовать этот объект автоматически, я использовал метод _asdict()
из 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
Кажется, что я должен сообщить сериализатору, как он может сгенерировать строку из объекта datetime
, что кажется для меня это невозможно без изменения pycouchdbs
исходного кода .
Единственный рабочий обходной путь, кажется, использует string
вместо datetime
в модели SensorMeasure
и использует isoformat()
метод datetime
. Но для этого мне потребуется
- установить дополнительные библиотеки для синтаксического анализа
- Я должен анализировать его при каждом использовании с накладными расходами на создание нового объекта, укажите формат, ...
С точки зрения дизайна, было бы намного лучше иметь атрибут 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