In Python können wir die JSON Schema Bibliothek verwenden, um ein JSON-Dokument anhand eines Schemas zu validieren.
In Python kann die JSON- Schemabibliothek verwendet werden, um ein JSON-Dokument anhand eines Schemas zu validieren. Ein JSON-Dokument kann eine beliebige Anzahl von Schlüssel/Wert-Paaren enthalten. Der Schlüssel muss eine Zeichenfolge sein, aber der Wert kann jeder unterstützte Typ sein, z. B. Zeichenfolge, Zahl, Boolescher Wert usw. Der Wert kann sogar komplexe Typen wie ein Array oder ein verschachteltes Objekt sein. Dies macht das JSON-Dokument sowohl sehr flexibel als auch sehr unstrukturiert.
Dies kann jedoch die Datenverarbeitung erschweren, da das Datenteam die Daten häufig über APIs erhält , deren Antworten normalerweise im JSON-Format vorliegen . Ein konsistentes Datenformat kann die Datenpipelines robuster machen. Mit einem einheitlichen Dateninput müssen Sie sich keine Gedanken über unerwartete Datentypen machen oder zu viel Zeit mit der Datenbereinigung verbringen, sodass Sie sich stärker auf die Datenanalyse konzentrieren und effizienter arbeiten können.
In diesem Beitrag stellen wir vor, wie Sie JSON Schema zum Validieren von JSON-Dokumenten verwenden. Wir behandeln die wesentlichen Konzepte sowie grundlegende und erweiterte Anwendungsfälle zusammen mit einfachen Codeausschnitten, die leicht zu befolgen sind.
Was ist ein JSON Schema?
Ein JSON Schema ist ein JSON-Dokument, das das Schema einiger JSON-Daten definiert. Diese Erklärung ist ziemlich seltsam und schwer verständlich, aber sie wird verständlicher, wenn wir uns den Code ansehen. Im Moment müssen wir zwei Punkte verstehen:
- Ein JSON Schema ist ein gültiges JSON-Dokument mit Schlüssel/Wert-Paaren. Jeder Schlüssel hat eine besondere Bedeutung und wird verwendet, um das Schema einiger JSON-Daten zu definieren.
- Ein Schema ähnelt der Tabellendefinition in einer SQL- Datenbank und definiert die Datentypen der Felder in einem JSON. Es definiert auch, welche Felder erforderlich und welche optional sind.
Beginnen wir mit einem einfachen JSON Schema:
Dieses JSON Schema gibt an, dass das Ziel-JSON ein Objekt mit zwei Eigenschaften ist, die auch allgemein als Schlüssel/Felder bezeichnet werden und entsprechend verwendet werden, und dass die nameEigenschaft erforderlich ist. Lassen Sie uns etwas tiefer in jedes Validierungsschlüsselwort eintauchen:
- Das typeSchlüsselwort gibt an, dass das Ziel-JSON ein Objekt ist. Es kann auch ein Array sein , was normalerweise ein Array von Objekten für API-Antworten ist. Wir werden später im Artikel besprechen, wie das Schema eines Array-Felds definiert wird. In den meisten Fällen ist die oberste Ebene jedoch typefast immer ein Objekt .
- Das propertiesSchlüsselwort gibt das Schema für jedes Feld des JSON-Objekts an. Jedes Feld des Ziel-JSON wird als Schlüssel/Wert-Paar angegeben, wobei der Schlüssel der eigentliche Feldname und der Wert der Typ des Felds im Ziel-JSON ist. Das Schlüsselwort typefür jedes Feld hat dieselbe Bedeutung wie das Schlüsselwort der obersten Ebene. Das typehier kann auch object sein . In diesem Fall wäre das entsprechende Feld ein verschachteltes Objekt, wie später gezeigt wird.
- Das requiredSchlüsselwort ist ein Array, das die erforderlichen Eigenschaften enthält. Wenn eine der hier angegebenen Eigenschaften fehlt, ValidationErrorwird ein Fehler ausgelöst.
Neben den wesentlichen Validierungsschlüsselwörtern, nämlich und type, die oben angegeben sind, gibt es weitere Schemaschlüsselwörter, die in der Online-Dokumentation und auch in den JSON Schemas zu finden sind, die einige Tools automatisch generieren.propertiesrequired
Wichtige Schlüsselwörter für das Python-JSON Schema
Es gibt zwei Schemaschlüsselwörter, nämlich $schema und $id . $schemadefiniert den „ Entwurf “, der für das Schema verwendet wird. Wenn $schemanicht angegeben, wird der neueste Entwurf verwendet, was normalerweise erwünscht ist. Sie könnten sich als Anfänger verirren, wenn Sie zu tief in die Entwürfe eintauchen. Normalerweise müssen wir das Feld nicht berühren $schema, aber wir werden dieses Konzept am Ende dieses Beitrags durchgehen.
Definiert andererseits $ideinen Uniform Resource Identifier (URI) für das Schema, der das aktuelle Schema extern von anderen Schemas aus zugänglich macht. Wenn $idnicht angegeben, kann das aktuelle Schema nur lokal verwendet werden, was normalerweise für kleine Projekte erwünscht ist. Für größere Projekte verfügt Ihre Institution jedoch möglicherweise über ein internes System zum Speichern und Referenzieren der Schemas. In diesem Fall können Sie das $id Schlüsselwort entsprechend festlegen.
Es gibt zwei Annotationsschlüsselwörter, nämlich titleund description, die den Titel bzw. die Beschreibung für das JSON Schema angeben. Sie können zur Dokumentation verwendet werden und können Ihr Schema leichter lesbar und verständlich machen. Sie werden auch von einigen grafischen Tools gut dargestellt. Der Einfachheit halber werden sie in diesem Beitrag nicht angegeben, aber Sie sollten sie normalerweise Ihrem Projekt hinzufügen, um eine optimale Vorgehensweise zu gewährleisten.
So validieren Sie ein JSON-Dokument anhand eines JSON Schemas in Python
In Python können wir die Bibliothek verwenden , um eine JSON-Instanz (auch als JSON-Dokument bezeichnet, solange es eindeutig ist) anhand eines Schemas zu validieren. Sie kann mit pip installiert werden :jsonschema
Lassen Sie uns einige JSON-Instanzen anhand des oben definierten JSON Schemas validieren. Technisch gesehen ist JSON eine Zeichenfolge, aber wir müssen die zugrunde liegenden Daten des zu validierenden JSON angeben, was praktischer ist.
Es zeigt, dass das definierte Schema wie erwartet zum Validieren der JSON-Instanzen verwendet werden kann. Falsche Datentypen oder das Fehlen einiger erforderlicher Felder lösen das aus ValidationError. Es ist jedoch zu beachten, dass standardmäßig zusätzliche Felder zulässig sind, die möglicherweise Ihren Wünschen entsprechen oder nicht. Wenn Sie ein striktes Schema wünschen und nur Felder zulassen, die durch das propertiesSchlüsselwort definiert sind, können Sie Folgendes additionalPropertiesangeben False:
Definieren Sie ein JSON Schema für ein Array-Feld in Python
Obwohl es nicht so üblich ist, ein Array als Feld der obersten Ebene zu haben, ist es sehr üblich, es als Eigenschaft zu haben. Fügen wir unserem oben definierten Schema eine Array-Eigenschaft hinzu. Wir müssen es auf „ typebe“ setzen und den Typ für jedes Element mit dem Schlüsselwort arrayangeben :items
Der Typ der Array-Elemente kann korrekt überprüft werden . Leere Arrays sind jedoch standardmäßig zulässig. Um dieses Verhalten zu ändern, können wir es minItemsauf eins oder die erwartete Zahl setzen, die in Ihrem Fall sinnvoll ist.
So definieren Sie das JSON Schema für ein verschachteltes Objektfeld in Python
Das typeSchlüsselwort einer Eigenschaft hat dieselbe Bedeutung und Syntax wie das Schlüsselwort der obersten Ebene. Wenn das Schlüsselwort einer Eigenschaft also objecttype ist , dann ist diese Eigenschaft ein verschachteltes Objekt. Fügen wir addressunseren JSON-Daten eine Eigenschaft hinzu, die ein verschachteltes Objekt sein wird:
Das Feld für verschachtelte Objekte weist genau dieselbe Schemadefinitionssyntax auf wie das Feld auf oberster Ebene. Daher ist es relativ einfach, die Schemata für verschachtelte Objekte zu definieren.
Verwenden Sie $defs, um Code-Duplizierung im JSON Schema zu vermeiden
Was passiert, wenn das addressFeld an mehreren Stellen im selben Schema verwendet werden muss? Wenn wir die Felddefinition überall dort kopieren, wo sie benötigt wird, kommt es zu Code-Wiederholungen, die Programmierer hassen, weil sie nicht dem „Don’t Repeat Yourself“-Prinzip (DRY) entsprechen. In JSON Schema können wir das Schlüsselwort verwenden , um kleine Unterschemata zu definieren, auf die an anderen Stellen verwiesen werden kann, um Code-Duplikationen zu vermeiden. Lassen Sie uns unser obiges Schema umgestalten, um möglicherweise Code-Duplikationen zu vermeiden:$defs $defs
Das neue Schema $defszur Definition eines Unterschemas funktioniert genauso wie bisher. Es hat jedoch den Vorteil, dass Code-Duplikationen vermieden werden können, wenn das addressFeld an verschiedenen Stellen desselben Schemas verwendet werden muss.
So legen Sie das JSON Schema für ein Tupelfeld in Python fest
Was ist, wenn das Feld ein Tupelscores mit einer festen Anzahl von Elementen sein soll ? Leider gibt es im JSON Schema kein Tupelfeld und wir müssen die Definition eines Tupels durch ein Array erreichen. Die allgemeine Logik ist, dass ein Array Elemente ( ) und optional einige positionell definierte Elemente hat, die vor den normalen Elementen ( ) stehen. Für ein Tupel gibt es nur aber keine , die den Effekt erzielen, dass ein Tupel eine feste Anzahl von Elementen hat. Und wichtig ist, dass der Typ für jedes Tupelelement explizit definiert werden muss.itemsprefixItemsprefixItemsitems
Wenn Sie das Schema für ein Tupelfeld definieren möchten, müssen Sie sich mit JSON Schemaentwürfen auskennen, was etwas fortgeschrittener ist. Ein Entwurf ist ein Standard oder eine Spezifikation für das JSON Schema und definiert, wie das Schema von einem Validator analysiert werden soll. Es sind mehrere Entwürfe verfügbar .
Normalerweise müssen wir uns nicht um das $schema- Feld und den zu verwendenden Entwurf kümmern. Wenn wir jedoch ein Tupelfeld definieren müssen, sollten wir darauf achten.
Wenn die installierte Bibliothek die neueste Version ist (v4.9.0 zum Zeitpunkt des Schreibens), wird der neueste Entwurf ( 2020–12 ) verwendet. Wenn dies die gewünschte Version ist, müssen Sie den Entwurf nicht mit dem Schlüsselwort angeben. Aus Gründen der Übersichtlichkeit empfiehlt es sich jedoch, die Version des Entwurfs immer in Ihrem JSON Schema anzugeben. Wir haben es der Einfachheit halber am Anfang dieses Beitrags weggelassen, es wird jedoch empfohlen, es in der Praxis zu verwenden.jsonschema $schema
Wenn Sie hingegen eine andere Entwurfsversion als die neueste verwenden möchten, müssen Sie das $schemaSchlüsselwort mit der Entwurfsversion explizit angeben. Andernfalls funktioniert es nicht richtig.
Lassen Sie uns das Schema für scoresdas Feld mit den Entwürfen 2020–12 bzw. 2019–09 definieren und zeigen, wie das $schemaSchlüsselwort verwendet wird und wie entsprechend ein Tupelfeld definiert wird:
Wie wir sehen, ist die Schemadefinition für das Tupelfeld mit dem Entwurf 2020–12 mithilfe der Schlüsselwörter und intuitiver prefixItemsund itemswird daher zur Verwendung empfohlen. Eine ausführlichere Erläuterung der Änderungen von 2019–09 bis 2020–12 bezüglich der Tupelfelddefinition finden Sie in den Versionshinweisen .
Außerdem ist zu beachten, dass das scoresFeld, selbst wenn es ein Tupel sein soll, für den Validator als Array (Liste in Python) und nicht als Tupel angegeben werden muss. Andernfalls funktioniert es nicht.
Verwenden eines Validators zum effizienten Validieren mehrerer JSON-Dokumente in Python
Wenn Sie über ein gültiges JSON Schema verfügen und es zum Validieren vieler JSON-Dokumente verwenden möchten, empfiehlt sich die Verwendung der Validator.validateMethode, die effizienter ist als die jsonchema.validateAPI. Ein Validator ist eine spezielle Klasse, die einen bestimmten Entwurf implementiert. Es gibt beispielsweise Draft202012Validator, Draft201909Validator und Draft7Validatorusw. Wenn im Klassennamen keine Entwurfsversion angegeben ist, Validatorbezeichnet selbst das Protokoll (ähnlich einer Schnittstelle), an das sich alle Validatorklassen halten sollen account executive.
Neben der Validator.validateMethode, die ähnlich wie die jsonchema.validateAPI funktioniert, können Sie Validator.check_schemaauch überprüfen, ob ein Schema für einen bestimmten Entwurf gültig ist. Sie können auch Validator.is_validstillschweigend überprüfen, ob ein JSON gültig ist oder nicht, ohne dass eine ValidationErrorMeldung ausgegeben wird, wenn es ungültig ist. Lassen Sie uns die Verwendung dieser Methoden anhand einiger einfacher Beispiele demonstrieren, die sie leichter verständlich machen:
In diesem Beitrag haben wir erklärt, was ein JSON Schema ist und wie man es verwendet, um verschiedene Datentypen in einem JSON-Dokument zu validieren. Wir haben die Grundlagen für einfache Datentypen wie Zeichenfolgen und Zahlen sowie komplexe Datentypen wie Arrays und verschachtelte Objekte behandelt. Wir haben auch gelernt, wie man Code-Duplikationen mit dem $defsSchlüsselwort vermeidet, das zum Definieren von Unterschemata verwendet wird und bei komplexen Schemata nützlich sein kann. Zu guter Letzt werden die Grundlagen von Entwürfen vorgestellt.
Wir wissen jetzt, wie man das Schema eines Tupelfelds mit verschiedenen Entwürfen definiert und wie man mit einem Validator, der einen bestimmten Entwurf verwendet, mehrere JSON-Dokumente effizienter anhand desselben Schemas validiert.