Как хранить и извлекать неструктурированные примитивные пары ключ-значение SQL в Python?

У меня есть несколько неструктурированных пар ключ-значение, которые я в конечном итоге хочу хранить в базе данных PostgreSQL, используя фреймворк Django. Данные типизированы с использованием примитивных типов SQL, так что это, казалось бы, звучит тривиально.

Например:

data = {
   "name": "bob", 
   "size": Decimal("173.4"), 
   "logged_in_at": datetime.now()
}

Однако я не могу просто создать Model и таблицу для нее, поскольку данные неструктурированы и могут иметь любое имя поля. (Однако я могу убедиться, что имя соответствует правилам синтаксиса Python и SQL).

Я не могу использовать JSONField или JSON в целом, потому что он не может надежно обрабатывать datetime и Decimal.

Я мог бы использовать BinaryField для хранения пиксельных данных, но боюсь последствий для безопасности.

Я могу динамически создавать сериализаторы для Django REST framework и связанных с ним моделей, но не знаю необходимых абстрактных мета-вуду и как работать с изменениями в базовых моделях данных во время выполнения.

Я бегло взглянул на MessagePack, похоже, что у него те же проблемы, что и у JSON.

Протокольные буферы хотя бы имеют тип Timestamp, но не имеют десятичного типа. Применение старого трюка "представить десятичные числа как целые" приведет к потере информации о типе и сделает целые числа неотличимыми от десятичных.

Поскольку это всего лишь одно поле, введение дополнительной базы данных NoSQL кажется излишеством. Кроме того, по крайней мере, MongoDB, похоже, не имеет встроенного десятичного типа данных.

В настоящее время я склоняюсь к написанию JSON кодера и декодера, который преобразует все поля в str и префикс с информацией о типе, например:

encoded_data = {
   "name": "string:bob", 
   "size": "decimal:173.4", 
   "logged_in_at": "datetime:2022-01-04T00:54:14.245607"  # ISO format
}

Тогда я мог бы хранить это в JSONField или даже CharField.

Однако это кажется большим количеством кода, шагов и процессора для такой, казалось бы, простой задачи.

Есть ли лучшие решения?

Вернуться на верх