Peewee'nin modelini PostgreSQL'e kaydetmeye çalıştığımda bu problemle karşılaştım JSONField
.
Bir süre mücadele ettikten sonra, işte genel çözüm.
Çözümümün anahtarı Python'un kaynak kodundan geçiyor ve kod belgelerinin ( burada açıklanan ) zaten mevcut json.dumps
olanın diğer veri türlerini destekleyecek şekilde nasıl genişletileceğini açıkladığını fark etmektir .
Geçerli olarak, JSON için serileştirilemeyen bazı alanları içeren bir modeliniz olduğunu ve JSON alanını içeren modelin aslında şöyle göründüğünü varsayalım:
class SomeClass(Model):
json_field = JSONField()
Bunun JSONEncoder
gibi bir özel tanımlamanız yeterlidir :
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)
Ve sonra JSONField
aşağıdaki gibi kullanın :
class SomeClass(Model):
json_field = JSONField(dumps=CustomJsonEncoder.json_dumper)
Anahtar default(self, obj)
yukarıdaki yöntemdir. ... is not JSON serializable
Python'dan aldığınız her bir şikayet için, serileştirilemeyen-JSON türünü ( Enum
veya gibi datetime
) işlemek için kod eklemeniz yeterlidir.
Örneğin, nasıl bir sınıf devralan destek burada 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)
Son olarak, kod yukarıdaki gibi uygulandığında, herhangi bir Peewee modelini aşağıdaki gibi bir JSON seriazable nesnesi haline dönüştürebilirsiniz:
peewee_model = WhateverPeeweeModel()
new_model = SomeClass()
new_model.json_field = model_to_dict(peewee_model)
Yukarıdaki kod (biraz) Peewee özgü olsa da, ama bence:
- Genel olarak diğer ORM'ler (Django vb.)
- Ayrıca, nasıl
json.dumps
çalıştığını anladıysanız , bu çözüm genel olarak Python (sans ORM) ile de çalışır
Herhangi bir sorunuz varsa, lütfen yorum bölümüne gönderin. Teşekkürler!