Ich bin auf dieses Problem gestoßen, als ich versucht habe, Peewees Modell in PostgreSQL zu speichern JSONField
.
Hier ist die allgemeine Lösung, nachdem Sie eine Weile gekämpft haben.
Der Schlüssel zu meiner Lösung besteht darin, den Quellcode von Python durchzugehen und zu erkennen, dass in der Codedokumentation ( hier beschrieben ) bereits erläutert wird, wie der vorhandene Code erweitert werden kann json.dumps
, um andere Datentypen zu unterstützen.
Angenommen, Sie haben derzeit ein Modell, das einige Felder enthält, die nicht für JSON serialisierbar sind, und das Modell, das das JSON-Feld enthält, sieht ursprünglich folgendermaßen aus:
class SomeClass(Model):
json_field = JSONField()
Definieren Sie einfach einen Benutzer JSONEncoder
wie diesen:
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)
Und dann benutze es einfach JSONField
wie folgt:
class SomeClass(Model):
json_field = JSONField(dumps=CustomJsonEncoder.json_dumper)
Der Schlüssel ist die default(self, obj)
obige Methode. ... is not JSON serializable
Fügen Sie für jede einzelne Beschwerde, die Sie von Python erhalten, einfach Code hinzu, um den Typ "unserializable to JSON" (z. B. Enum
oder) zu verarbeitendatetime
) zu verarbeiten.
So unterstütze ich beispielsweise eine Klasse, die von Folgendes erbt 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)
Schließlich können Sie mit dem wie oben implementierten Code einfach alle Peewee-Modelle in ein JSON-seriazierbares Objekt wie das folgende konvertieren:
peewee_model = WhateverPeeweeModel()
new_model = SomeClass()
new_model.json_field = model_to_dict(peewee_model)
Obwohl der obige Code (etwas) spezifisch für Peewee war, denke ich:
- Es gilt allgemein für andere ORMs (Django usw.)
- Wenn Sie verstanden haben, wie es
json.dumps
funktioniert, funktioniert diese Lösung auch mit Python (ohne ORM) im Allgemeinen
Bei Fragen bitte in den Kommentaren posten. Vielen Dank!