当我尝试将Peewee的模型存储到PostgreSQL中时遇到了这个问题 JSONField
。
经过一段时间的努力,这是一般的解决方案。
我的解决方案的关键是浏览Python的源代码,并意识到代码文档(在此描述)已经解释了如何扩展现有的json.dumps
以支持其他数据类型。
假设您当前有一个模型,其中包含一些无法序列化为JSON的字段,并且包含JSON字段的模型最初看起来像这样:
class SomeClass(Model):
json_field = JSONField()
只需这样定义一个自定义JSONEncoder
:
class CustomJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, SomeTypeUnsupportedByJsonDumps):
return < whatever value you want >
return json.JSONEncoder.default(self, obj)
@staticmethod
def json_dumper(obj):
return json.dumps(obj, cls=CustomJsonEncoder)
然后JSONField
像下面这样使用它:
class SomeClass(Model):
json_field = JSONField(dumps=CustomJsonEncoder.json_dumper)
关键是default(self, obj)
上面的方法。对于... is not JSON serializable
您从Python收到的每一个投诉,只需添加代码来处理从unserializable-to-JSON类型(例如Enum
或datetime
)
例如,这是我如何支持从继承的类Enum
:
class TransactionType(Enum):
CURRENT = 1
STACKED = 2
def default(self, obj):
if isinstance(obj, TransactionType):
return obj.value
return json.JSONEncoder.default(self, obj)
最后,使用上述实现的代码,您可以将任何Peewee模型转换为JSON可序列化的对象,如下所示:
peewee_model = WhateverPeeweeModel()
new_model = SomeClass()
new_model.json_field = model_to_dict(peewee_model)
尽管上面的代码(某种程度上)特定于Peewee,但是我认为:
- 通常适用于其他ORM(例如Django等)
- 另外,如果您了解其
json.dumps
工作原理,那么该解决方案通常也适用于Python(无ORM)
如有任何疑问,请发表在评论部分。谢谢!