{"id":173038,"date":"2023-03-27T14:52:38","date_gmt":"2023-03-27T13:52:38","guid":{"rendered":"https:\/\/liora.io\/de\/?p=173038"},"modified":"2026-02-06T06:57:56","modified_gmt":"2026-02-06T05:57:56","slug":"api-erstellen-mit-verschiedenen-apps-teil-i","status":"publish","type":"post","link":"https:\/\/liora.io\/de\/api-erstellen-mit-verschiedenen-apps-teil-i","title":{"rendered":"API erstellen mit verschiedenen Apps (Teil I)"},"content":{"rendered":"<p><strong>Wir haben in den drei vorherigen Artikeln ein erstes Beispiel f\u00fcr die Programmierung einer Web-API unter Flask gesehen, wie man eine Web-API mit einer SqLite-Datenbank verbindet und wie man eine Web-API mit Python, Flask, Swagger und Connexion programmiert und dokumentiert. In diesem und dem n\u00e4chsten Artikel werden wir uns ansehen, wie man diese Elemente mit der Verwaltung einer Datenbank unter Verwendung von SQLAlchemy und Marshmallow kombiniert.<\/strong><\/p>\n<h3>1. Technische Voraussetzungen<\/h3>\nBeginnen wir mit der Installation der <a href=\"https:\/\/liora.io\/de\/top-10-der-python-bibliotheken-fur-data-scientists\">Python-Bibliotheken,<\/a> die wir unter Anaconda ben\u00f6tigen, mit dem folgenden Befehl in einem Terminalfenster:\n<ul>\n \t<li>$ conda install -c conda-forge<a href=\"https:\/\/liora.io\/de\/api-mit-python-datenbank-verbinden\"> Flask-SQLAlchemy<\/a> flask- marshmallow marshmallow-sqlalchemy marshmallow.<\/li>\n<\/ul>\nMit diesem Befehl werden die folgenden Bibliotheken installiert:\n<ul>\n \t<li>flask-SQLAlchemy, die den Zugriff auf Datenbanken in einer mit Flask kompatiblen Weise erm\u00f6glicht.<\/li>\n \t<li>flask-marshmallow, mit der du Python-Objekte in serialisierbare Strukturen umwandeln kannst (d. h. die als eine Folge von kleineren Informationen kodiert werden k\u00f6nnen).<\/li>\n \t<li>marshmallow-sqlalchemy, das die Serialisierung und Deserialisierung von Python-Objekten erm\u00f6glicht, die von SQLAlchemy erzeugt wurden.<\/li>\n \t<li>marshmallow, das den Gro\u00dfteil der Marshmallow-Funktionen zur Serialisierung\/Deserialisierung bereitstellt.<\/li>\n<\/ul>\n<h3>2. Allgemeiner \u00dcberblick<\/h3>\nIm dritten Artikel wurde gezeigt, wie man mithilfe von Python, <a href=\"https:\/\/liora.io\/de\/api-mit-python-datenbank-verbinden\">Flask,<\/a> Connexion und Swagger eine REST-API erstellt, die <strong>CRUD-Operationen zul\u00e4sst und gut dokumentiert ist.<\/strong>\n\nDie Daten wurden jedoch in einer PEOPLE-Struktur gespeichert, die bei jedem Start des Servers zur\u00fcckgesetzt wurde.\n\nIm Folgenden werden wir uns ansehen, wie man die PEOPLE-Struktur und die von der API bereitgestellten Aktionen mithilfe von SQLAlchemy und Marshmallow dauerhaft in einer Datenbank speichert.\n\nSQLAlchemy bietet ein Object Relational Model (ORM), das es erm\u00f6glicht, die Daten von Python-Objekten in einer datenbank\u00e4hnlichen Darstellung zu speichern.\n\nDies erm\u00f6glicht es, weiterhin im Sinne von <a href=\"https:\/\/liora.io\/de\/webhooks-in-python-was-sind-sie-und-wie-kann-man-sie-mit-python-verwenden\">Python<\/a> zu programmieren, ohne sich um die Details der Darstellung der Daten eines Objekts in der Datenbank k\u00fcmmern zu m\u00fcssen.\n\nMarshmallow bietet Werkzeuge, um Python-Objekte zu serialisieren und deserialisieren, w\u00e4hrend sie von unserer REST-API im JSON-Format gesendet oder empfangen werden.\n\nMarshmallow wandelt insbesondere Instanzen von Python-Klassen in Objekte um, die in JSON umgewandelt werden k\u00f6nnen.\n\n<a href=\"https:\/\/github.com\/salimlardjane1\/projects\/tree\/version_3\">Den entsprechenden Code zu diesem Artikel findest du hier<\/a>\n<h3>3. Daten<\/h3>\nIm dritten Artikel hatten wir unsere Daten durch ein Python-W\u00f6rterbuch dargestellt, dessen Schl\u00fcssel die Nachnamen der in der <a href=\"https:\/\/liora.io\/de\/datenbank-data-management-weiterbildung\">Datenbank<\/a> vorhandenen Personen waren.\n\nDer entsprechende Code lautete wie folgt:\n\nDie \u00c4nderungen, die du vornehmen wirst, werden die Daten in eine <a href=\"https:\/\/liora.io\/de\/sql-alles-uber-die-datenbanksprache\">Tabelle einer Datenbank \u00fcbertragen.<\/a>\n\nDas bedeutet, dass die Daten &#8222;fest&#8220; gespeichert werden und zwischen zwei Ausf\u00fchrungen von server.py zug\u00e4nglich sind.\n\nDa der Nachname der Schl\u00fcssel zum <strong>Python-W\u00f6rterbuch PEOPLE<\/strong> war, verhinderte der Code, dass der Name einer Person ge\u00e4ndert werden konnte. Die \u00dcbertragung in eine Datenbank wird diese \u00c4nderung erlauben, da der Nachname nicht mehr als Schl\u00fcssel verwendet wird.Konzeptionell kann man sich eine Datenbank als eine zweidimensionale Tabelle vorstellen, in der jede Zeile einem Datensatz und jede Spalte einem Feld des Datensatzes entspricht.\n\nDatenbanken verf\u00fcgen oft \u00fcber einen selbst erstellten Index, mit dem die Zeilen identifiziert werden k\u00f6nnen.\n\nDies wird als Prim\u00e4rschl\u00fcssel bezeichnet.\n\nJedem Datensatz in der Tabelle entspricht ein eindeutiger Wert des Prim\u00e4rschl\u00fcssels.\n\nDie Tatsache, dass wir einen von unseren Daten unabh\u00e4ngigen Prim\u00e4rschl\u00fcssel haben, erlaubt es uns, jedes andere Feld in den Datens\u00e4tzen zu \u00e4ndern, einschlie\u00dflich des Nachnamens.\n\nWir \u00fcbernehmen eine Standardkonvention f\u00fcr Datenbanken, indem wir der Tabelle einen singul\u00e4ren Namen geben: Wir nennen sie person.\n<h3>4. Interaktion mit der Datenbank<\/h3>\nWir werden <a href=\"https:\/\/liora.io\/de\/sql-tutorial\">SQLite<\/a> als Datenbank-Engine verwenden, um die PEOPLE-Daten zu speichern.\n\nSQLite ist die meistverbreitete Datenbank der Welt und steht standardm\u00e4\u00dfig unter Python zur Verf\u00fcgung.\n\nSie ist schnell, arbeitet mit Dateien und eignet sich f\u00fcr viele Arten von Projekten.\n\nEs handelt sich um ein vollst\u00e4ndiges RDBMS (Relational DataBase Management System), das auch <strong>SQL<\/strong> beinhaltet.\n\nAngenommen, die Tabelle person existiert in einer SQLite-Datenbank.\n\nDann kann man <strong>SQL<\/strong> verwenden, um die Daten abzurufen.\n\nIm Gegensatz zu Programmiersprachen wie Python sagt <a href=\"https:\/\/liora.io\/de\/sql-tutorial\">SQL<\/a> nicht, wie die Daten abgerufen werden sollen, sondern gibt nur an, welche Daten ben\u00f6tigt werden, und \u00fcberl\u00e4sst das Wie der Datenbankmaschine.\n\nEine SQL-Abfrage, um eine Liste aller Personen in unserer Datenbank abzurufen, die alphabetisch nach Nachnamen sortiert ist, sieht folgenderma\u00dfen aus:\n\nSELECT * FROM person ORDER BY &#8218;lname&#8216;;\n\nDu kannst die obige Abfrage nach dem Start von SQLite mit folgendem Befehl in einem Terminalfenster absetzen\n\n$ sqlite3 people.db\n\nwas zu folgendem Ergebnis f\u00fchrt:\n\nSHELL\n\nsqlite&gt; select * from person order by &#8218;lname&#8216;;\n1|Dupont|Jean|2022-04-24 09:30:48.713385\n2|Durand|Louise|2022-04-24 09:30:48.715009\n3|Lopez|Francois|2022-04-24 09:30:48.716247\n\nDie vorherige Ausgabe entspricht allen Datens\u00e4tzen der Datenbank, wobei die einzelnen Felder durch das &#8222;Pipe&#8220;-Zeichen | getrennt sind.\n\nTats\u00e4chlich ist es m\u00f6glich, die vorherige Abfrage direkt von Python aus zu \u00fcbermitteln. Das Ergebnis w\u00e4re eine Liste von Tupeln. Die Liste enth\u00e4lt alle Datens\u00e4tze, wobei jedes Tupel einem Datensatz entspricht.\n\nDie Daten auf diese Weise abzurufen, ist jedoch nicht wirklich mit dem Geist von Python vereinbar.\n\nEine Liste zu erhalten passt gut zu Python, aber Tupel zu haben ist problematisch: Der Programmierer muss den Index jedes Feldes kennen, um auf die Daten zugreifen zu k\u00f6nnen.\n\n<a href=\"https:\/\/liora.io\/de\/api-mit-python-datenbank-verbinden\">In Python w\u00fcrde man folgenderma\u00dfen vorgehen:<\/a>\n\nDas vorherige Programm l\u00e4uft folgenderma\u00dfen ab:\n\nZeile 1 importiert das Modul sqlite3.\n\nZeile 3 erstellt eine Verbindung zur Datenbankdatei.\n\nZeile 4 erstellt einen Verbindungscursor (der die Datenbank durchsuchen wird).\n\nZeile 5 verwendet den Cursor, um eine SQL-Anfrage auszuf\u00fchren, die als Zeichenkette ausgedr\u00fcckt wird.\n\nZeile 6 ruft alle von der SQL-Abfrage zur\u00fcckgegebenen Datens\u00e4tze ab und weist sie der Variablen people zu.\n\nDie Zeilen 7 und 8 iterieren \u00fcber die Liste people und drucken den Vor- und Nachnamen jeder Person aus.\n\nDie Variable people hat folgende Struktur:\n\n[(1, &#8218;Dupont&#8216;, &#8218;Jean&#8216;, &#8218;2022-04-24 09:30:48.713385&#8216;),\n(2, &#8218;Durand&#8216;, &#8218;Louise&#8216;, &#8218;2022-04-24 09:30:48.715009&#8216;),\n(3, &#8218;Lopez&#8216;, &#8218;Francois&#8216;, &#8218;2022-04-24 09:30:48.716247&#8216;)]\n\nDas Ergebnis der Ausf\u00fchrung des vorherigen Programms ist wie folgt:\n<ul>\n \t<li>Jean Dupont<\/li>\n \t<li>Louise Durand<\/li>\n \t<li>Francois Lopez<\/li>\n<\/ul>\nIm vorherigen Programm muss man wissen, dass der Nachname an Position 1 und der Vorname an Position 2 in den zur\u00fcckgegebenen Tupeln steht.\n\nAu\u00dferdem muss die interne Struktur von person bekannt sein, wenn man die Iterationsvariable person als Parameter an eine Funktion oder Methode \u00fcbergibt.\n\nEs w\u00e4re viel praktischer, person als<strong> Python-Objekt<\/strong> zu haben, wobei die verschiedenen Felder den Attributen des Objekts entsprechen.\n\nDies kann mit SQLAlchemy gemacht werden.\n\n<em>&gt;&gt; Auch interessant: <\/em>\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center\"><div class=\"wp-block-button \"><a class=\"wp-block-button__link wp-element-button \" href=\"https:\/\/liora.io\/de\/olap-alles-ueber-diese-leistungsstarke-datenbankstruktur\">OLAP Datenbankstruktur<\/a><\/div><\/div>\n\n<h3>5. Das Risiko der SQL-Injection<\/h3>\nIm vorherigen Programm ist die<strong> SQL-Abfrage<\/strong> eine einfache Zeichenkette, die zur Ausf\u00fchrung an die Datenbank \u00fcbergeben wird.\n\nDies ist kein Problem, da die Zeichenkette vollst\u00e4ndig unter der Kontrolle des Programmierers steht.\n\nIm Gegensatz dazu wird unsere Webanwendung von einer Benutzereingabe in die REST-API ausgehen, um eine SQL-Abfrage zu erstellen.\n\nDies kann eine Sicherheitsl\u00fccke in unserer Anwendung darstellen.\n\nDie <strong>REST-API-<\/strong>Anfrage f\u00fcr den Zugriff auf eine bestimmte Person hat die Form :\n\nGET \/api\/people\/{lname}.\n\nDas bedeutet, dass die API eine Variable, lname, im URL-Pfad erwartet, die sie verwendet, um eine bestimmte Person zu finden.\n\nDer entsprechende Python-Code hat die folgende Form:\n\nDer vorherige Code funktioniert wie folgt:\n\nIn Zeile 1 wird der Wert der Variablen lname auf &#8218;M\u00fcller&#8216; gesetzt. Dies w\u00fcrde aus dem URL-Pfad im Rahmen der API stammen.\n\nDer von Zeile 2 erzeugte SQL-Code hat folgende Form:\n\nSQL\n\nSELECT * FROM person WHERE lname = &#8218;Dupont&#8216;.\n\nWenn diese SQL-Abfrage von der Datenbank ausgef\u00fchrt wird, wird die entsprechende Person in der Datenbank gesucht und die zugeh\u00f6rigen Informationen abgerufen.\n\nDies ist die erwartete Funktionsweise; ein b\u00f6swilliger Benutzer kann jedoch in diesem Arbeitsrahmen eine SQL-Injektion (SQL-Injection) durchf\u00fchren.\n\nZum Beispiel k\u00f6nnte ein b\u00f6swilliger Benutzer die <a href=\"https:\/\/liora.io\/de\/api\">API<\/a> wie folgt anfordern:\n\nGET \/api\/people\/Farrell&#8216;);DROP TABLE person;\n\nDie vorherige Abfrage setzt den Wert der Variablen lname auf: &#8218;M\u00fcller&#8216;);DROP TABLE person;&#8216;, wodurch die folgende SQL-Abfrage erzeugt wird:\n\nSQL\n\nSELECT * FROM person WHERE lname = &#8218;Dupont&#8216;);DROP TABLE person;\n\nDie vorherige SQL-Abfrage ist g\u00fcltig.\n\nSie w\u00fcrde die Tabelle zun\u00e4chst nach einer Person namens &#8222;M\u00fcller&#8220; durchsuchen und dann, wenn sie auf ein Semikolon st\u00f6\u00dft, zur n\u00e4chsten Abfrage \u00fcbergehen, die die gesamte Tabelle person l\u00f6scht.\n\nEs ist klar, dass dies unsere Anwendung au\u00dfer Gefecht setzen w\u00fcrde.\n\nEine M\u00f6glichkeit, dies zu vermeiden, besteht darin, die von den Nutzern gelieferten Daten zu filtern, um sicherzustellen, dass sie nichts enthalten, was f\u00fcr die Anwendung gef\u00e4hrlich ist.\n\nDies kann kompliziert sein, vor allem, da man alle Interaktionen der Nutzer mit der Datenbank untersuchen m\u00fcsste.\n\nEine praktischere L\u00f6sung ist die Verwendung von <strong>SQLAlchemy.<\/strong>\n\nSQLAlchemy filtert die Anfragen der Benutzer an die Datenbank, bevor es die entsprechenden SQL-Abfragen erstellt.\n\nDies ist ein weiterer Grund,<strong> SQLAlchemy<\/strong> zu verwenden, wenn du mit webbasierten Datenbanken arbeitest.\n<h3>6. Das SQLAlchemy-Modell<\/h3>\n<strong>QLAlchemy<\/strong> ist ein wichtiges Projekt und stellt sehr viele Werkzeuge zur Verf\u00fcgung, mit denen man unter Python mit Datenbanken arbeiten kann.\n\nEines der Werkzeuge, die es zur Verf\u00fcgung stellt, ist ein <strong>ORM (Object Relational Mapper).<\/strong>\n\nDiesen werden wir benutzen, um die Datenbank person in Python zu erstellen und mit ihr zu arbeiten.\n\nDie<strong> objektorientierte Programmierung (OOP)<\/strong> erm\u00f6glicht es, Daten und ihre Manipulation, d. h. die Funktionen, die auf den Daten operieren, miteinander zu verkn\u00fcpfen.\n\nDurch das Erstellen von<strong> SQLAlchemy-Klassen<\/strong> k\u00f6nnen Datenbankfelder mit bestimmten Arten von Manipulationen verkn\u00fcpft werden, wodurch eine Interaktion mit den Daten erm\u00f6glicht wird.\n\nDie <strong>SQLAlchemy-Klassen<\/strong> definieren die Daten in der Tabelle person wie folgt:\n\nDie<strong> Klasse Person<\/strong> erbt von db.model, das die Attribute und Funktionen f\u00fcr die Manipulation von Datenbanken bereitstellt.\n\nDie<strong> restlichen Definitionen<\/strong> entsprechen den Attributen der Klasse.\n\n__tablename__ = person stellt die Verbindung zwischen der Klasse Person und der Tabelle person her.\n\nperson_id = db.Column(db.Integer, primary_key = True) erstellt eine Spalte in der Datenbank, die eine ganze Zahl enth\u00e4lt, die als Prim\u00e4rschl\u00fcssel verwendet wird. Dies impliziert, dass person_id ein selbstinkrementierter Integerwert ist.\n\nlname = db.Column(db.String) erstellt das Feld &#8222;Nachname&#8220;, d. h. eine Spalte in der Datenbank, die Zeichenketten enth\u00e4lt.\n\nname = db.Column(db.String) erstellt das Feld &#8222;vorname&#8220;, d. h. eine Spalte in der <a href=\"https:\/\/liora.io\/de\/sql-alles-uber-die-datenbanksprache\">Datenbank<\/a>, die Zeichenketten enth\u00e4lt.\n\ntimestamp = db.Column(db.DateTime, default = datetime.utcnow, on update = datetime.utcnow)erstellt das Feld &#8222;timestamp&#8220;, d. h. eine Spalte in der Datenbank, die Datums-\/Zeitwerte enth\u00e4lt.\n\nDer Parameter default = datetime.utcnow setzt als Standardwert f\u00fcr den &#8222;Zeitstempel&#8220; den aktuellen Wert utcnow, wenn ein Datensatz erstellt wird. Ebenso aktualisiert update = datetime.utcnow den &#8222;timestamp&#8220; mit dem Wert utcnow, wenn der Datensatz aktualisiert wird.\n\nWarum wird utcnow als &#8222;timestamp&#8220; verwendet?\n\nTats\u00e4chlich gibt die Methode datetime.utcnow( )den aktuellen UTC-Zeitpunkt zur\u00fcck (UTC: Universal Time Coordinated). Dies ist eine M\u00f6glichkeit, den &#8222;Zeitstempel&#8220; zu standardisieren.\n\nDies erm\u00f6glicht insbesondere einfachere Berechnungen von Datums-\/Zeitangaben.\n\nWenn man von verschiedenen Zeitzonen aus auf die App zugreift, reicht es, die Zeitzone zu kennen, um die Daten\/Zeiten umzurechnen.\n\nEs w\u00e4re komplizierter, wenn man einen &#8222;Zeitstempel&#8220; in lokale Daten\/Zeiten verwenden w\u00fcrde.\n\nWas bringt uns die Klasse Person?\n\nDie Idee ist, die Tabelle mithilfe von SQLAlchemy abzufragen und als Ergebnis eine Liste von Instanzen der Klasse Person zu erhalten.\n\nAls Beispiel nehmen wir die vorherige<a href=\"https:\/\/liora.io\/de\/sql-tutorial\"><strong> SQL-Abfrage:<\/strong><\/a>\n\nSQL\n\nSELECT * FROM people ORDER BY lname;\n\nMithilfe von SQLAlchemy sieht die Abfrage wie folgt aus:\n\nIgnorieren wir Zeile 1 zun\u00e4chst.\n\n<strong>Die Anweisung SQLAlchemy<\/strong> Person.query.order_by(Person.lname).all( )liefert eine Liste von Objekten der Klasse Person, die allen Datens\u00e4tzen in der Tabelle person entsprechen und nach Nachnamen sortiert sind.\n\nDie Variable people enth\u00e4lt die Liste der Objekte.\n\nDann iteriert das Programm \u00fcber die Variable people, indem es nacheinander den Vor- und Nachnamen jeder in der Datenbank vorhandenen Person ausgibt.\n\nBeachte, dass das Programm die Felder fname und lname nicht indiziert, sondern die Attribute der Person-Objekte verwendet.\n\nDie Verwendung von <a href=\"https:\/\/liora.io\/de\/datenbank-data-management-weiterbildung\">SQLAlchemy<\/a> erm\u00f6glicht es, in Objekten statt in SQL-Abfragen zu denken. Je gr\u00f6\u00dfer die Datenbank ist, desto praktischer und interessanter ist es.\n<h3> 7. Serialisierung<\/h3>\nDie Arbeit mit dem <strong>SQLAlchemy-Modell<\/strong> ist in Bezug auf die Programmierung sehr praktisch.\n\nEs ist vor allem praktisch, wenn du Programme schreibst, die Daten manipulieren und Berechnungen mit ihnen durchf\u00fchren.\n\nDie Anwendung, die wir hier im Auge haben, ist jedoch eine REST-API, die CRUD-Operationen auf Daten bereitstellt und daher nicht mit sehr unterschiedlichen oder komplizierten Datenmanipulationen verbunden ist.\n\nUnsere <a href=\"https:\/\/liora.io\/de\/api\">REST-API<\/a> arbeitet mit Daten im JSON-Format, was ein Kompatibilit\u00e4tsproblem mit dem SQLAlchemy-Modell darstellen kann.\n\nDa die von SQLAlchemy zur\u00fcckgegebenen Daten Python-Objekte (Instanzen von Python-Klassen) sind, kann das Connexion-Modul sie nicht in das JSON-Format umwandeln.\n\nWir erinnern daran, dass Connexion das Modul ist, das zur Implementierung unserer API verwendet wird, die mithilfe einer YAML-Datei konfiguriert wird.\n\nSerialisierung ist die Umwandlung eines Python-Objekts in einfachere Datenstrukturen, die mithilfe von JSON-Datentypen (JSON datatypes) formatiert werden k\u00f6nnen; diese sind unten aufgelistet:\n\nstring: Zeichenkette\nnumber: von Python zugelassene Zahlen (integers, floats, long)\nobject: entspricht grob den Python-W\u00f6rterb\u00fcchern.\narray: entspricht grob den Python-Listen.\nboolean: nimmt unter JSON die Werte true oder false an, unter Python jedoch True oder False.\nnull: entspricht None unter Python.\n\nAls Beispiel: Die Klasse Person enth\u00e4lt einen &#8222;timestamp&#8220;, der ein Python DateTime-Objekt ist.\n\nEs gibt kein \u00c4quivalent unter JSON, also muss das DateTime-Objekt in eine Zeichenkette umgewandelt werden, um unter JSON manipuliert werden zu k\u00f6nnen.\n\nDie Klasse Person ist eigentlich einfach genug, um in Betracht zu ziehen, die Attribute zu extrahieren und manuell W\u00f6rterb\u00fccher zu erstellen, die den <strong>URLs unserer API entsprechen.<\/strong>\n\nIn komplexeren Situationen mit gr\u00f6\u00dferen<strong> SQLAlchemy<\/strong>-Mustern ist dies jedoch nicht mehr der Fall.\n\nWir greifen daher auf ein Modul namens Marshmallow zur\u00fcck, das die Arbeit f\u00fcr uns \u00fcbernimmt.\n<h3>8. Marshmallow<\/h3>\nMarshmallow erm\u00f6glicht es, eine Klasse &#8222;PersonSchema&#8220; zu erstellen, die das Gegenst\u00fcck zur Klasse &#8222;Person&#8220; ist, die du unter<strong> SQLAlchemy<\/strong> erstellt hast.\n\nAnstatt jedoch die Datenbanktabellen und ihre Felder auf Klassen und ihre Attribute abzubilden, definiert die Klasse PersonSchema, wie die Attribute einer Klasse in ein JSON-Format umgewandelt werden.\n\nHier ist die Marshmallow-Klassendefinition f\u00fcr die Daten in unserer Tabelle &#8222;person&#8220; :\n\nDie Klasse PersonSchema erbt von der Klasse ma.ModelSchema.\n\nDiese ist eine Marshmallow-Basisklasse und bietet eine Reihe von Attributen und Funktionen, die es erm\u00f6glichen, Python-Person-Objekte in JSON zu serialisieren und JSON-Daten als Instanzen der Klasse Person zu deserialisieren (die umgekehrte Operation).\n\nDer Rest der Definition l\u00e4uft wie folgt ab:\n\nclass Meta: Definiert eine Klasse mit dem Namen Meta innerhalb unserer Klasse. Die ModelSchema-Klasse, von der PersonSchema erbt, sucht nach dieser internen Meta-Klasse und verwendet sie, um das <strong>SQLAlchemy-Modell<\/strong> Person und die Datenbanksitzung db.session zu finden. Dies erm\u00f6glicht Marshmallow, die Attribute der Klasse Person zu serialisieren\/deserialisieren.\n\nmodel: Gibt die <strong>SQLAlchemy-Vorlage<\/strong> an, die zum Serialisieren\/Deserialisieren von Daten verwendet werden soll.\n\ndb.session: Gibt die Datenbanksitzung an, die f\u00fcr die Introspektion, d. h. die Untersuchung und Bestimmung von Attributtypen, verwendet werden soll.\n<h3>9. Erstellen der Datenbank<\/h3>\nAn diesem Punkt haben wir beschlossen, SQLALchemy zu verwenden, um unsere Datenbank zu manipulieren, was uns erlaubt, uns auf das Datenmodell und die Art und Weise, wie wir sie manipulieren, zu konzentrieren.\n\nJetzt werden wir unsere Datenbank erstellen.\n\nDazu werden wir <strong>SQLite<\/strong> verwenden.\n\nWir werden <strong>SQLite<\/strong> aus zwei Gr\u00fcnden verwenden:\n\nSie wird standardm\u00e4\u00dfig mit Python geliefert und muss daher nicht als separates Modul installiert werden.\nSie speichert alle Informationen in einer einzigen Datei und ist daher einfach einzurichten und zu verwenden.\n\nEs w\u00e4re m\u00f6glich, einen separaten Datenbankserver wie MySQL oder PostgreSQL zu verwenden, aber das w\u00fcrde bedeuten, diese Systeme zu installieren und in Betrieb zu nehmen, was weit \u00fcber den Zweck dieser Artikelserie hinausgeht.\n\nDa die Datenbank mithilfe von <strong>SQLAlchemy<\/strong> manipuliert wird, sind die Details ihrer Implementierung nicht wichtig.\n\nWir werden ein Programm build_database.py erstellen, um die SQLite-Datenbank people.db, die unsere Daten enthalten wird, zu erstellen und zu initialisieren.\n\nDabei werden wir zwei Zusatzmodule config.py und models.py erstellen, die von build_database.py und server.py verwendet werden.\n\n<strong>config.py<\/strong>: wird sich um den Import und die Konfiguration der verschiedenen ben\u00f6tigten Module k\u00fcmmern. Dazu geh\u00f6ren Flask, Connection, SQLAlchemy und Marshmallow. Da sie sowohl von build_database.py als auch von server.py verwendet wird, wird ein Teil der Konfiguration nur auf server.py angewendet.\n\n<strong>models.py:<\/strong> Dies ist das Modul, das f\u00fcr die Erstellung der Klasse SQLAlchemy Person und der Klasse Marshmallow PersonSchema zust\u00e4ndig ist. Dieses Modul wird \u00fcber bestimmte Objekte, die in config.py erstellt und konfiguriert wurden, vom Modul config.py abh\u00e4ngen.\n<h4>Das Konfig-Modul<\/h4>\nDas Modul config.py fasst alle Konfigurationsinformationen zusammen.\n\nHier ist der entsprechende Code :\n\nDie Zeilen 2-4 importieren <strong>Connexion, SQLAlchemy<\/strong> und Marshmallow.\n\nZeile 6 erstellt die Variable basedir, die auf das Verzeichnis zeigt, in dem das Programm ausgef\u00fchrt wird.\n\nZeile <strong>9 verwendet die Variable<\/strong> basedir, um die Instanz der Anwendung Connexion zu erstellen, und gibt ihr den Pfad zur Konfigurationsdatei swagger.yml an.\n\nZeile 12 erstellt eine Variable app, die der Flask-Instanz entspricht, die von Connexion initialisiert wird.\n\nZeile 15 verwendet die Variable app, um <strong>SQLAlchemy<\/strong> zu konfigurieren.\n\nWir beginnen damit,<strong> SQLAlchemy_ECHO<\/strong> auf True zu setzen, was dazu f\u00fchrt, dass die von SQLAlchemy ausgef\u00fchrten SQL-Abfragen an die Konsole zur\u00fcckgegeben werden.\n\nDies ist sehr n\u00fctzlich in der Entwicklungs- und Debugging-Phase.\n\nIn der Produktionsumgebung setzt man sie auf False.\n\nZeile 19 setzt SQLALCHEMY_DATABASE_URI auf &#8222;sqlite:\/\/\/\/&#8220; + os.path.join(basedir, &#8222;people.db&#8220;).\n\nDies weist SQLALchemy an, SQLite als Datenbank und eine Datei namens people.db im aktuellen Verzeichnis als Datendatei zu verwenden.\n\nAndere Datenbank-Engines, wie MySQL oder PostgreSQL, w\u00fcrden mit einer anderen SQLALCHEMY_DATABASE_URI konfiguriert werden.\n\nZeile 20 setzt SQLALCHEMY_TRACK_MODIFICATIONS auf False, wodurch das standardm\u00e4\u00dfig aktive Ereignisbehandlungssystem SQLAlchemy deaktiviert wird.\n\nDieses System ist n\u00fctzlich f\u00fcr Programme, die auf Ereignissen (Klicks, &#8230;) basieren, verlangsamt aber die Ausf\u00fchrung. Da unser Programm nicht ereignisbasiert ist, schalten wir es aus.\n\nIn Zeile 22 wird die Variable db durch Aufruf von SQLAlchemy(app) erstellt.\n\nDies initialisiert SQLAlchemy mit den Konfigurationsinformationen, die wir gerade angegeben haben. Die Variable db wird in das Programm build_database.py importiert, um ihm Zugriff auf SQLAlchemy und die Datenbank zu geben. Dasselbe wird in den Modulen server.py und people.py geschehen.\n\nZeile 25 erstellt die Variable ma durch einen Aufruf von Marshmallow(app). Dies initialisiert Marshmallow und erlaubt die Introspektion von SQLAlchemy-Komponenten, die an die Datenbank angeh\u00e4ngt sind. Marshmallow muss daher nach SQLAlchemy initialisiert werden.\n<h4>Das Models-Modul<\/h4>\nDas models.py-Modul wird verwendet, um die Klassen SQLAlchemy Person und Marshmallow PersonSchema zu definieren, wie zuvor gesehen.\n\nHier ist der entsprechende Code:\n\nZeile 1 importiert die Klasse datetime aus dem Modul datetime, das standardm\u00e4\u00dfig in Python verf\u00fcgbar ist.\n\nZeile 2 importiert die Objekte db und ma aus dem Modul config.py. Dadurch erh\u00e4lt das Programm Zugriff auf die SQLAlchemy-Attribute und Methoden, die an das db-Objekt angeh\u00e4ngt sind, sowie auf die Marshmallow-Attribute und Methoden, die an das ma-Objekt angeh\u00e4ngt sind.\n\nDie<strong> Zeilen 4-11 definieren die Klasse Person<\/strong> so, dass sie die SQLAlchemy-Funktionen nutzen kann, wie z. B. die Verbindung zu einer Datenbank und den Zugriff auf ihre Tabellen.\n\nDie Zeilen 14-17 definieren die Klasse PersonSchema so, dass sie von den <strong>Marshmallow-Funktionen<\/strong> profitiert. So erm\u00f6glicht die Introspektion auf die Klasse Person die Serialisierung\/Deserialisierung der Instanzen dieser Klasse.\n<h4>Erstellen einer Datenbank<\/h4>\nWir haben gesehen, wie Tabellen in einer Datenbank mit SQLAlchemy-Klassen abgebildet werden k\u00f6nnen.\n\nJetzt werden wir die Datenbank erstellen und ihr Daten zuweisen.\n\nDazu verwenden wir das folgende Programm <strong>build_database.py:<\/strong>\n\nZeile 2 importiert das db-Objekt aus dem Modul config.py.\n\nZeile 3 importiert die Klasse Person aus dem Modul models.py.\n\nDie Zeilen 6 bis 10 erstellen die Struktur PEOPLE, die eine Liste von W\u00f6rterb\u00fcchern ist, die die Daten enthalten. Beachte, dass eine solche Struktur leicht z. B. aus einer <strong>CSV-Datei erstellt werden kann.<\/strong>\n\nDie Zeilen 13 und 14 r\u00e4umen ein wenig auf, indem sie die Datei people.db l\u00f6schen, falls sie bereits existiert. Dadurch wird sichergestellt, dass du bei Null anf\u00e4ngst, wenn du die Datenbank neu erstellen musst.\n\nZeile 17 erstellt die Datenbank mithilfe des Aufrufs db.create_all( ). Dies erstellt die Datenbank unter Verwendung der db-Instanz, die aus dem config-Modul importiert wurde. Die db-Instanz ist unsere Verbindung zur Datenbank.\n\nDie Zeilen 20 bis 22 iterieren \u00fcber die PEOPLE-Liste und verwenden die darin enthaltenen W\u00f6rterb\u00fccher, um die Klasse Person zu instanziieren.\n\nNachdem diese instanziiert wurde, rufen wir die Funktion db.session.add(p) auf.\n\nDie Verbindungsinstanz db wird verwendet, um auf das Session-Objekt zuzugreifen.\n\nDie Sitzung ist das, was die Aktionen verwaltet, die in der Datenbank ausgef\u00fchrt werden.\n\nHier f\u00fchren wir die Methode add(p) aus, um eine neue Instanz von Person zum Session-Objekt hinzuzuf\u00fcgen.\n\nIn Zeile 24 wird db.session.commit( ) aufgerufen, um alle erstellten Person-Objekte in der Datenbank zu speichern.\n\nIn Zeile 22 ist noch nichts in der Datenbank gespeichert; alles wird im Session-Objekt gespeichert. Erst nach der Ausf\u00fchrung von db.session.commit( ) interagiert die Sitzung mit der Datenbank und wendet die angegebenen Aktionen auf sie an.\n\nUnter SQLAlchemy ist die Sitzung ein wichtiges Objekt. Sie verbindet die Datenbank und die SQLAlchemy-Objekte, die in einem Python-Programm manipuliert werden.\n\nSie sorgt daf\u00fcr, dass die Daten im Programm und die Daten in der Datenbank konsistent bleiben.\n\nAlle ausgef\u00fchrten Aktionen werden in der Datenbank gespeichert und sie aktualisiert die Datenbank entsprechend den expliziten oder impliziten Aktionen, die im Programm ausgef\u00fchrt werden.\n\nJetzt k\u00f6nnen wir die Datenbank erstellen und initialisieren.\n\nF\u00fchre einfach das Programm build_database.py aus, z. B. in Spyder.\n\nWenn das Programm ausgef\u00fchrt wird, zeigt es die Meldungen von SQLAlchemy auf der Konsole an. Das liegt daran, dass wir <strong>SQLALCHEMY_ECHO<\/strong> im config.py-Modul auf True gesetzt haben.\n\nDas meiste, was angezeigt wird, sind die von <strong>SQLAlchemy<\/strong> erzeugten SQL-Abfragen, um die Datenbankdatei people.db zu erstellen und zu f\u00fcllen.\n\nWir werden im n\u00e4chsten Artikel sehen, wie wir unsere API mit all den Werkzeugen, die uns jetzt zur Verf\u00fcgung stehen, aktualisieren k\u00f6nnen.\n<h3>10.  Bibliografische Referenzen<\/h3>\n<ul>\n \t<li><i>Creating Web APIs with Python and Flask, <\/i>Patrick Smyth, 2022 :<a href=\"https:\/\/programminghistorian.org\/en\/lessons\/creating-apis-with-python-and-flask\"> https:\/\/programminghistorian.org\/en\/lessons\/creating-apis-with-python-and-flask<\/a>.<\/li>\n \t<li><i>Python REST APIs With Flask, Connexion, and SQLAlchemy<\/i>, Doug Farrell, 2022 :&nbsp; <a href=\"https:\/\/realpython.com\/flask-connexion-rest-api\/\">https:\/\/realpython.com\/flask-connexion-rest-api\/<\/a>.&nbsp;&nbsp;<\/li>\n \t<li><i>Python REST APIs With Flask, Connexion, and SQLAlchemy<\/i>, Doug Farrell, 2022 : <a href=\"https:\/\/realpython.com\/flask-connexion-rest-api-part-2\/\">https:\/\/realpython.com\/flask-connexion-rest-api-part-2\/<\/a>.<\/li>\n \t<li><i>Flask RESTful documentation<\/i>, 2020 :<a href=\"https:\/\/flask-restful.readthedocs.io\/en\/latest\/index.html\"> https:\/\/flask-restful.readthedocs.io\/en\/latest\/index.html<\/a>.<\/li>\n \t<li><i>Flask Web Development : Developing Web Applications with Python<\/i> (2\u00e8me \u00e9dition). M. Grinberg. O\u2019Reilly 2018.&nbsp;<\/li>\n \t<li><i>Architectural Styles and the Design of Network-Based Software Architectures<\/i>. T. Fielding. Th\u00e8se, University of California, 2000.<\/li>\n<\/ul>\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex is-content-justification-center\"><div class=\"wp-block-button \"><a class=\"wp-block-button__link wp-element-button \" href=\"https:\/\/liora.io\/de\/unsere-aus-und-weiterbildungen\">Mehr \u00fcber unsere Data Science Weiterbildungen<\/a><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Wir haben in den drei vorherigen Artikeln ein erstes Beispiel f\u00fcr die Programmierung einer Web-API unter Flask gesehen, wie man eine Web-API mit einer SqLite-Datenbank verbindet und wie man eine Web-API mit Python, Flask, Swagger und Connexion programmiert und dokumentiert. In diesem und dem n\u00e4chsten Artikel werden wir uns ansehen, wie man diese Elemente mit [&hellip;]<\/p>\n","protected":false},"author":74,"featured_media":173039,"comment_status":"open","ping_status":"open","sticky":false,"template":"elementor_theme","format":"standard","meta":{"_acf_changed":false,"editor_notices":[],"footnotes":""},"categories":[2476],"class_list":["post-173038","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-dev"],"acf":[],"_links":{"self":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts\/173038","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/users\/74"}],"replies":[{"embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/comments?post=173038"}],"version-history":[{"count":1,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts\/173038\/revisions"}],"predecessor-version":[{"id":217655,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/posts\/173038\/revisions\/217655"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/media\/173039"}],"wp:attachment":[{"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/media?parent=173038"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/liora.io\/de\/wp-json\/wp\/v2\/categories?post=173038"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}