Heim >Technologie-Peripheriegeräte >IT Industrie >Die Ecto -Bibliothek
Elixir ist eine moderne, dynamische, funktionale Programmiersprache, mit der hochverteilte und fehlertolerante Anwendungen erstellt werden. ECTO ist die Hauptbibliothek für die Arbeit mit Datenbanken und bietet Tools, um mit Datenbanken unter einer gemeinsamen API zu interagieren, die Datenbank neben unserer Anwendung zu verarbeiten und die Datenverarbeitung in unserer Anwendung zu verarbeiten.
Dieser Artikel sieht sich den Hauptaspekten der ECTO -Bibliothek kurz an. Während es für ECTO 1.x geschrieben ist, sind die Beispiele in diesem Artikel mit ECTO 2 kompatibel und wenn Diskrepanzen liegen, werden sie erwähnt. Grundkenntnisse über Elixier und Mix werden angenommen.
Erstellen einer neuen Anwendung
mix new notex <span>--sup </span>Das - -SUP -Flag generiert einen zusätzlichen Boilerplate -Code, der für eine OTP -Anwendung erforderlich ist. Diese Anwendung muss einen Überwachungsbaum haben, da Ecto ihn benötigt (mehr dazu in einer Minute).
Einrichten der Abhängigkeiten
Aktualisieren Sie die Anwendung/0 -Funktion in der Datei mix.exs mit Folgendes:
<span>def <span>application</span> do </span> <span>[applications: [:logger, :ecto, :mariaex], </span> <span>mod: {Notex, []}] </span><span>end </span>und aktualisieren Sie DEPS/0 mit Folgendes:
defp deps <span>do </span> <span>[{:ecto, <span>"~> 1.1.5"</span>}, # or "~> 2.0" for Ecto 2 </span> <span>{:mariaex, <span>"~> 0.6.0"</span>}] # or "~> 0.7.0" for Ecto 2 </span><span>end </span>holen Sie jetzt die Abhängigkeiten mit Mix Deps.get.
Als nächstes müssen wir diese Abhängigkeiten in unsere Anwendung integrieren. Auf diese Weise werden ein neues Wrapper -Modul für ein ECTO -Repository erstellt, das Überwachungsbaum unserer Anwendung aktualisiert, um dieses neue Modul zu starten und zu beaufsichtigen, und die Verbindung der Adapterinformationen des Adapters zu konfigurieren.
Beginnen wir zunächst mit dem folgenden Code mit dem folgenden Code:
, zunächst ein nonex.repo -Modul zu definieren:mix new notex <span>--sup </span>
Der Ort dieses Moduls (lib/app_name/repo.ex) ist konventionell. Jedes Mal, wenn wir einen Mix Ecto -Befehl verwenden, sucht es standardmäßig nach dem definierten Repository unter appname.repo. Wir können es woanders platzieren, aber es wird die Unannehmlichkeiten haben, seinen Standort mit der Flag -r- (oder -repo) -Fahne anzugeben.
Mit dem obigen Notex.Repo -Modul können wir mit ECTO mit Datenbanken arbeiten. Dies erfolgt zunächst Funktionen aus dem Repo -Modul von Ecto (die die Datenbank -Abfrage -API bereitstellen) und durch zweite Benennung unserer OTP -Anwendung als: Notex.
Ein ECTO -Repository bietet uns eine gemeinsame Schnittstelle, um mit einer zugrunde liegenden -Datenbank
zu interagieren (die durch den verwendeten Adapter entschieden wird). Während Ecto das Terminology Repo verwendet, folgt es nicht dem Repository -Designmuster, da es sich um eine Wrapper um eine Datenbank handelt, nicht um eine Tabelle.Jetzt, da wir das Notex.Repo -Modul definiert haben, müssen wir dies jetzt zu unserem Überwachungsbaum im Notex -Modul (unter lib/nonex.ex) hinzufügen. Aktualisieren Sie die Start/2 -Funktion mit Folgendem:
<span>def <span>application</span> do </span> <span>[applications: [:logger, :ecto, :mariaex], </span> <span>mod: {Notex, []}] </span><span>end </span>
Wir haben das Notex.Repo -Modul als Kindermodul hinzugefügt (da es selbst eine überwiegende OTP -App ist). Dies bedeutet, dass es von unserer OTP -Anwendung beaufsichtigt wird und unsere Bewerbung für den Start des Antrags starten wird.
Jede mit ECTO erstellte Verbindung verwendet einen separaten Prozess (bei dem der Prozess mit einer Bibliothek namens Poolboy aus einem Prozesspool gezogen wird). Dies geschieht, damit unsere Fragen gleichzeitig ausgeführt werden und von Fehlern (z. B. Zeitüberschreitungen) belastbar sind. Unsere Anwendung erfordert daher OTP, da ECTO über eigene Prozesse verfügt, die überwacht werden müssen (einschließlich eines Überwachungsbaums, der einen Pool von Datenbankverbindungen überwacht). Dies ist mit der Erlang -Observer -Bibliothek zu sehen, mit der wir die Prozesse in einer Anwendung visualisieren können. Nachdem wir das Repo zu unseren Arbeitsprozessen hinzugefügt haben, um zu überwachen, müssen wir den Adapter zuletzt so konfigurieren, dass er mit unserer Datenbank kommunizieren kann. Platzieren Sie den folgenden Code am Ende der Datei `config/config.exs` (aktualisiert die Details nach Bedarf):
mix new notex <span>--sup </span>Hier geben wir den Namen unserer OTP -Anwendung (: Notex) und den Namen unseres frisch definierten Moduls (Notex.Repo) an, um die Kommunikation mit der Datenbank zu aktivieren. Die anderen Konfigurationsoptionen sollten ziemlich selbsterklärend sein. Nach ECTO 2 müssen wir zusätzlich eine Liste der ECTO -Repos angeben, die wir in unserer Anwendung verwenden.
ecto bietet uns tatsächlich eine Abkürzung zum Einrichten des obigen Repo -Moduls als Mix -Aufgabe: Mix ecto.gen.repo. Dies generiert das Repository -Modul für uns und aktualisiert die Datei config.exs mit einer grundlegenden Konfiguration (das Repo -Modul muss jedoch noch manuell zum Überwachungsbaum hinzugefügt werden). Ich habe es vermieden, es hier vorwiegend aus didaktischen Gründen zu verwenden, um zu zeigen, wie ECTO manuell eingerichtet werden kann (das, und die Tatsache, dass der Repo -Generator annimmt, dass Sie Postgres verwenden, müssten wir den Adapter in der Konfiguration sowieso aktualisieren).
Bevor Sie fortfahren, schauen wir uns die Prozesshierarchie sehr schnell an. (Beachten Sie, dass Sie, wenn Sie ECTO 2 ausführen, zunächst die Datenbank mit mix ecto.create erstellen müssen, bevor Sie versuchen, das Projekt zu kompilieren.) Starten
<span>def <span>application</span> do </span> <span>[applications: [:logger, :ecto, :mariaex], </span> <span>mod: {Notex, []}] </span><span>end </span>Navigiert auf die Registerkarte Anwendung, können wir die Prozesse der Anwendung sehen, einschließlich der Vorgesetzten:
Erstellen der Datenbank und Tabellen
, um die Datenbank zu erstellen:
defp deps <span>do </span> <span>[{:ecto, <span>"~> 1.1.5"</span>}, # or "~> 2.0" for Ecto 2 </span> <span>{:mariaex, <span>"~> 0.6.0"</span>}] # or "~> 0.7.0" for Ecto 2 </span><span>end </span>
Um die Tabellen zu erstellen, verwenden wir die Migrationsfunktion von Ecto. Migrationen ermöglichen es uns, die Datenbank neben dem Quellcode zu verstellen, sodass Änderungen nachverfolgt und verschiedene Zustände angewendet werden können. Wir erstellen daher neue Migrationen, wenn wir die Struktur der Datenbank ändern möchten.
Eine neue Migration kann mit dem Befehl mix ecto.gen.Migration erstellt werden wie folgt:
defmodule Notex<span>.Repo do </span> use Ecto<span>.Repo, otp_app: :notex </span><span>end </span>
Das obige sollte einen neuen Migrationsordner unter priv/repo/migrationen sowie eine neue migrationsdatei erstellen. Diese Datei wird mit dem erstellten Datum und die Zeit (für die einfache Verzeichnisbestellung) zusammen mit unserem Migrationsnamen vorangestellt. Öffnen Sie diese Datei und ändern Sie sie in Folgendes:
mix new notex <span>--sup </span>
Wenn wir die Dinge einfach halten, haben wir das Makro erstellen, um eine neue Tabelle (genannte Notizen) mit zwei Feldern zu definieren: Note_Name und Note_Content. Der Primärschlüssel wird für uns automatisch erstellt (mit dem Namen ID). Während unsere beiden Felder als einfache Zeichenfolgen definiert wurden, unterstützt Ecto viele Typen - die Sie in seiner Dokumentation überprüfen können.
Mit unserer Migration können wir jetzt die Migration mit dem folgenden Befehl ausführen:
<span>def <span>application</span> do </span> <span>[applications: [:logger, :ecto, :mariaex], </span> <span>mod: {Notex, []}] </span><span>end </span>
Dies erstellt unsere Notizentabelle mit 3 Feldern (das dritte Feld ist ID, der Primärschlüssel).
Mit der erstellten Tabelle ist es jetzt an der Zeit, ein Modell für die Tabelle zu erstellen. Das Modell wird verwendet, um die Felder der Tabelle und deren jeweiligen Typen zu definieren. Diese werden von der Anwendung und der Abfrage von DSL von ECTO beim Gießen und Validieren der Daten verwendet. Modelldefinitionen können auch virtuelle Felder enthalten (im Gegensatz zu Migrationsdefinitionen), die verwendet werden, um typisch kurzlebige Daten zu halten, die wir nicht bestehen möchten (wie z. B. abgesperrte Passwörter).
In seiner grundlegendsten Form sieht unser Notex.note -Modell (das sich bei lib/notex/note.ex befindet) aus wie folgt:
defp deps <span>do </span> <span>[{:ecto, <span>"~> 1.1.5"</span>}, # or "~> 2.0" for Ecto 2 </span> <span>{:mariaex, <span>"~> 0.6.0"</span>}] # or "~> 0.7.0" for Ecto 2 </span><span>end </span>
Wir injizieren das Ecto.Schema -Modul, damit wir das Schema -Makro verwenden können, um die Felder und deren Typen zu definieren. Diese Definitionen werden später wichtig, wenn wir die Änderungen von Ecto verwendet haben. Etwas anderes, das das Schema -Makro für uns tut, ist eine Struktur des Typs als aktuelles Modul (in diesem Fall ist es %nonex.note {}). Diese Struktur ermöglicht es uns, neue Änderungen zu erstellen (in Kürze mehr) und Daten in die Tabelle einfügen.
Mit nur dem oben genannten können wir den IEX abbauen und anfangen, unsere Datenbank abzufragen:
defmodule Notex<span>.Repo do </span> use Ecto<span>.Repo, otp_app: :notex </span><span>end </span>
(Konsolen -Debugging -Informationen reduziert.)
Das Abfragemodul vonEcto wird importiert, um alle Abfragebeding -DSL -Makros (wie z. B. von) in der Shell zur Verfügung zu stellen. Anschließend erstellen wir eine einfache Abfrage, um alle Datensätze (mit All/1) zurückzugeben, wobei nur das Feld "Note_Name" ausgewählt wird. Dies kehrt eine leere Liste zurück, da wir derzeit keine Datensätze in der Datenbank haben. Erstellen wir einen neuen Änderungssatz und fügen Sie ihn in die Tabelle ein:
<span>def <span>start</span>(_type, _args) do </span> import Supervisor<span>.Spec, warn: false </span> children <span>= [ </span> supervisor<span>(Notex.Repo, []), </span> <span>] </span> opts <span>= [strategy: :one_for_one, name: Notex.Supervisor] </span> Supervisor<span>.start_link(children, opts) </span><span>end </span>
(Konsolen -Debugging -Informationen reduziert.)
wir beginnen mit zunächst ECTO.Query erneut, was für den letzten Abrufbetrieb benötigt wird (speziell für das aus dem Makro). Wir verwenden dann die Änderung/1 -Funktion von Ecto.Changeset, um einen neuen Änderungssatz mit einer %Notex.note {} struktur zu erstellen. Dieser Änderungssatz wird dann eingefügt und dann abgerufen.
Änderungen sind das, was wir bei der Arbeit mit Datensätzen verwenden. Sie ermöglichen es uns, Änderungen an den Daten vor dem Einfügen zu verfolgen, diese Änderungen zu validieren und ihre Werte auf die richtigen Datentypen zu geben (gemäß unserer Schema -Definition). Wie wir aus den oben genannten sehen können, enthält die Struktur � to.changeset {} eine Reihe von Mitgliedern, die nützlich sind, um zu sehen, ob die Änderungen gültig sind (Änderungenset.Valid?), Was sind die Fehler, wenn sie nicht waren (Änderungenset .rors) und so weiter.
Aktualisieren wir das notex.note -Modell, um einige Änderungen und Abfragebetriebe zu demonstrieren, da die Ausführung dieser in IEX ein wenig chaotisch wird:
mix new notex <span>--sup </span>
Lassen Sie uns jede der fünf neuen Funktionen durchlaufen. Die Funktion Insert_Note/1 erstellt für uns eine neue Notiz. Die Cast/4 -Funktion übernimmt das Gießen von Daten von den Eingabefeldern zu ihren jeweiligen Feldtypen (gemäß unserer Schema -Definition) und stellt sicher, dass alle erforderlichen Felder Werte haben. Der von Cast/4 zurückgegebene Änderungsset wird dann in die Datenbank eingefügt. Beachte
Die Funktion get_notes/0 gibt eine Liste von Tupeln aller Notizen in der Tabelle zurück. Dies geschieht durch Musteranpassung in der Auswahlanweisung. (Wir hätten ganz leicht eine Liste von Karten mit Auswahl: %{id: n.id, note_name: n.note_name} zurückgegeben können.)Die Funktion get_note/1 ruft eine einzelne Notiz aus der Tabelle gemäß der Notiz -ID ab. Dies geschieht über das Get! Funktion, die entweder die Notiz nach Erfolg zurückgibt oder nach dem Scheitern wirft.
Die Funktion update_note/1 aktualisiert einen Hinweis gemäß der angegebenen Notiz -ID. Beachten Sie die String -Taste in der Karte der Funktionssignatur (die ID -Taste). Dies ist eine Konvention, die ich aus dem Phoenix-Framework entnommen habe, in dem unansittete Daten (in der Regel benutzerversorgter) in Karten mit Stringschlüssel dargestellt werden, und sanitierte Daten werden in Karten mit Atomschlüssel dargestellt. Um das Update durchzuführen, rufen wir zuerst die Notiz gemäß der ID aus der Datenbank ab und verwenden dann die Cast/4 -Funktion, um die Änderungen auf den Datensatz anzuwenden, bevor sie schließlich den aktualisierten Änderungssatz in die Datenbank zurückfügen.
Die Funktion delete_note/1 entfernt einen Hinweis aus der Datenbank. Wir holen zuerst die Notiz aus der Datenbank über ihre ID (ähnlich der Funktion update_note/1) und löschen sie dann mit der zurückgegebenen Note Struct.
mit den oben genannten CRUD -Operationen gehen wir zurück in den IEX und probieren Sie es aus:
<span>def <span>application</span> do </span> <span>[applications: [:logger, :ecto, :mariaex], </span> <span>mod: {Notex, []}] </span><span>end </span>(Konsolen -Debugging -Informationen reduziert.)
Und da haben wir es, eine grundlegende CRUD -Anwendung mit Ecto! Wir könnten die Ausgabe wiederholen und die API netter machen, gegen die wir abfragen können, aber ich werde das als Erweiterung verlassen, da diese dem, was wir abdecken, tangential sind (und dieser Artikel ist lang genug, denke ich).
Schlussfolgerung
In meinem nächsten Artikel schaue ich mir die Grundlagen von Elixirs Ecto -Abfrage -DSL an.
Wie kann ich Ecto mit Phoenix verwenden? Phoenix verwendet ECTO für alle Datenmanipulationsanforderungen und bietet Generatoren, die es einfach machen, ECTO -Schemas, Änderungen und Migrationen zu erstellen. Sie können auch die Abfrage -API von Ecto direkt in Ihren Phoenix -Controllern und -ansichten verwenden.
Das obige ist der detaillierte Inhalt vonDie Ecto -Bibliothek. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!