Kopfschmerzfrei gespeicherte Objekte: Ein einfaches Beispiel für die Arbeit mit Caché-Objekten in ObjectScript und Python
Schloss NeuschwansteinIm Juni 2020 genau 50 Jahre tabellarische Data Warehouses oder formal ein relationales Datenmodell. Hier ist ein offizielles Dokument -
der gleiche berühmte Artikel . Dafür bedanken wir uns bei Dr. Edgar Frank Codd. Das relationale Datenmodell steht übrigens auf der Forbes-Liste der wichtigsten globalen Innovationen der letzten 100 Jahre.
Auf der anderen Seite betrachtete Codd seltsamerweise relationale Datenbanken und die SQL-Sprache als verzerrte Implementierung seiner Theorie. Als Leitfaden entwickelte er sogar 12 Regeln, die jedes relationale Datenbankverwaltungssystem erfüllen muss (tatsächlich sind dies 13 Regeln). Und in Wahrheit gibt es heute auf der Welt keine DBMS, die mindestens Codds "Regel 0" erfüllen, und daher kann niemand ihr DBMS als 100% relational bezeichnen :) Vielleicht gibt es Ausnahmen, sagen Sie mir?
Das relationale Modell ist nicht sehr komplex und wird entlang und quer untersucht. Es kann sogar zu tief studiert werden. In der Zwischenzeit, in diesem Jahr 2019, werden wir auch ein weiteres Jubiläum feiern - vor genau 10 Jahren erschien der #NoSQL-Hashtag später „nicht nur SQL“ auf Twitter und begann schnell in die Praxis der Entwicklung von Datenbankmodellen einzudringen.
Warum so eine lange Einführung? Zu der Tatsache, dass das Programmieruniversum aus Daten (und natürlich Algorithmen) besteht und die Monopolstellung des relationalen Modells, wie höflicher zu sagen ist, zu einem gespaltenen Bewusstsein des Programmierers führt. Da die Arbeitsobjekte im Kopf des Entwicklers (OOP ist auch total, oder?), Sind alle diese Listen, Warteschlangen, Bäume, Heaps, Wörterbücher, Threads usw. keine Tabellen.
Und wenn Sie fortfahren und sich an die Speicherarchitektur in modernen DBMS erinnern? Nehmen wir direkt an, niemand, der bei klarem Verstand ist, speichert Daten in Form von Tabellen. DBMS-Entwickler verwenden am häufigsten Varianten des B-Baums (z. B. in PostrgeSQL) oder viel seltener wörterbuchbasierten Speicher. Andererseits arbeiten die Barrikaden, Entwickler, die DBMS zum Speichern verwenden, auch mit Nicht-Tabellen. Und dies zwingt Programmierer, die semantische Lücke ständig mit einer ungeschickten Zwischendatenschicht zu schließen. Und verursachen dadurch innere dichotome Spannungen, systemische Beschwerden und Debug-Schlaflosigkeit.
Kurz gesagt, es gibt einen Widerspruch: Wir packen die Daten in Objekte, die für die Aufgabe geeignet sind, und sollten beim Speichern einige Tabellen berücksichtigen.
Hoffnungslosigkeit? Nein :) Aber was ist mit der objektrelationalen Zuordnung, ist es im allgemeinen Volk von ORM? Überlassen wir
diesen heiligen Krieg Jegor Bugaenko mit Kameraden. Und diese ganze Geschichte aus dem letzten Jahrhundert
sollte uns laut Onkel Bob keine Sorgen machen .
Erwähnenswert ist natürlich, dass der „Beutel mit Bytes“ (Robert Martin „Pure Architecture“) serialisiert und in eine Datei abgelegt oder in einen anderen geeigneten Stream verschoben werden kann. Aber erstens wird es uns sofort in der Sprache einschränken, und zweitens werden wir uns jetzt nur noch um das Speichern im DBMS kümmern.
Es gibt eine angenehme Ausnahme zu diesen Höhen und Tiefen bei Byte-Beuteln - das Intersystems Caché DBMS (und jetzt die InterSystems IRIS-Datenplattform). Dies ist wahrscheinlich das einzige DBMS auf der Welt, das das Offensichtliche nicht vor dem Entwickler verbirgt und sogar noch weiter geht - es befreit einen davon, darüber nachzudenken, wie man alles richtig speichert. Es genügt zu sagen, dass die Klasse die Gattung Persistent fortsetzt und der Punkt im Hut
liegt, dh in globalen Zahlen (nicht zu verwechseln mit globalen Variablen!).
Alle Arten von Daten können gespeichert werden, einschließlich Zeichen- und Binärströme. Hier ist ein einfaches Beispiel:
// - // : , , , , Class FW.Events Extends %Persistent { Property "My name" As %String; } // // «» set haJS = ##class(FW.Events).%New() // write haJS.%Id()
Darüber hinaus können Sie mit gespeicherten Objekten nicht nur in ObjectScript, das in Caché enthalten ist, kommunizieren, sondern auch direkt in Python, Java, JavaScript, C ++, C # und Perl abrufen und speichern. Und sogar, oh Horror :). Es ist auch möglich, Informationen von denselben Objekten direkt über SQL-Abfragen abzurufen, und es ist auch möglich, eigene Methoden für Objekte aufzurufen. Genauer gesagt werden die Methoden in diesem Fall für sich (und das Zauberwort SqlProc) zu gespeicherten Prozeduren. Die ganze Magie steckt bereits unter der Haube des Caché DBMS.
Wie erhalte ich kostenlosen Testzugriff auf Intersystems Caché DBMS?
Das ist absolut real, egal was böse Sprachen sagen! :) Sie können die Einzelbenutzer-Vollversion von Caché hier herunterladen und installieren (Sie müssen sich kostenlos registrieren). Builds sind für MacOS, Windows und Linux verfügbar.
Am bequemsten ist es, mit ObjectScript-Code zu arbeiten und mit der auf Eclipse basierenden Atelier-IDE direkt auf den Caché DBMS-Server (und auch auf die InterSystems IRIS-Plattform) zuzugreifen. Alle
Download- und Installationsanweisungen finden Sie
hier .
Wem es bequemer und vertrauter ist, können Sie den komfortablen und einfachen Visual Studio-Code verwenden, der durch das von der Community entwickelte ObjectScript-Plug-In ergänzt wird.
Und nun ein paar praktische Beispiele. Versuchen wir, einige verwandte Objekte zu erstellen und mit ihnen in ObjectScript und Python zu arbeiten. Die Integration mit anderen Sprachen ist sehr ähnlich implementiert. Python wird aus Gründen der "maximalen Affinität" zu ObjectScript ausgewählt - beide Sprachen sind skriptfähig, unterstützen OOP und haben keine starke Typisierung :)
Als Ideen für Beispiele wenden wir uns an lebhafte Chabarowsk-Projekte (nicht zu verwechseln mit Chabrowsk!) Projekte des „Rahmens für Versammlungen“. Der ideologische Quellcode befindet sich unter
github.com/Hajsru/framework-weekend . Unser Quellcode enthält weniger Text.
Eine wichtige Nuance für MacOS-Benutzer. Wenn Sie die Support-Module für Python starten, müssen Sie berücksichtigen, dass Sie den Pfad DYLD_LIBRARY_PATH zu dem Verzeichnis angeben müssen, in dem Sie Caché installiert haben. Zum Beispiel so:
export DYLD_LIBRARY_PATH = / application / Cache / bin: $ DYLD_LIBRARY_PATH
Dies ist in der Dokumentation ausdrücklich angegeben .
Wir erstellen gespeicherte Klassen in ObjectScript
Also lass uns gehen. Der Unterricht bei Caché wird sehr einfach sein. Sie können auf eine IDE verzichten - kopieren Sie den Klassencode direkt über das Portal Ihrer Caché-Plattforminstanz (ja, Caché DBMS ist weit entfernt von einem DBMS): Systembrowser> Klassen> Importieren (Namespace USER).
Nach dem Speichern werden Objekte in den Globen mit Namen angezeigt, die mit den Namen der entsprechenden Klassen übereinstimmen. Schauen Sie auch im Caché-Verwaltungsportal nach: Systembrowser> Globals (Namespace USER).
// , , Class FW.Event Extends %Persistent { Property title as %String; Property description as %String; Property date as %Date; Property visitors as list of FW.Attendee; } // / Class FW.Attendee Extends %Persistent { Property name As %String; }
Zugriff auf Objekte in Caché über Python
Stellen Sie zunächst eine Verbindung zur Caché DBMS-Datenbank her. Wir wiederholen wie
in der Dokumentation .
Nur eine nützliche Tatsache, mit der man arbeiten kann. Kostenlos ist es auch eine Schulungsversion des Caché DBMS, mit der Sie alles tun können, was in der voll funktionsfähigen Version verfügbar ist, aber nur zwei aktive Verbindungen zulässt. Daher ist es gleichzeitig nicht möglich, eine Verbindung von der IDE aufrechtzuerhalten und zu versuchen, anderen Code für die Interaktion mit dem Server auszuführen. Die einfachste Lösung besteht darin, die IDE zu schließen, während der Python-Code ausgeführt wird.
Und jetzt erstellen wir eine Objektdatenbank mit IT-Ereignissen und ihren Teilnehmern. Sehr sehr einfach. Die erste besteht darin, eine Klasse zum Registrieren und Speichern von Informationen über den Veranstaltungsteilnehmer zu erstellen. Zur Vereinfachung der Klasse nur der Mitgliedsname.
Wie Sie sehen können, verwenden wir vorgefertigte Wrapper-Funktionen für den Zugriff auf die Felder von Objekten in Caché: set. In den Parametern übergeben wir den Eigenschaftsnamen in Anführungszeichen und openid mit dem Namen des Pakets und der Klasse. Über eine ähnliche get-Funktion gibt es unten Beispiele. Verwenden Sie die Funktion run_obj_method () mit dem Methodennamen und den Aufrufparametern, falls erforderlich, um auf andere Methoden zuzugreifen, einschließlich der von ihren Vorfahren geerbten Klasse.
Die wichtigste Magie in der Zeile: self.att.run_obj_method ("% Save", [])
Auf diese Weise können wir Objekte mit direkter Referenz speichern, ohne zusätzliche Bibliotheken und Frameworks / Frameworks wie die allgegenwärtigen und unansehnlichen ORMs verwenden zu müssen.
Aufgrund der objektorientierten Natur von ObjectScript und der Methoden seiner Klasse (in unserem Beispiel haben wir sie nicht ausgeführt) erhalten wir außerdem einen Bonus vom Python-Zugriff auf den gesamten Satz von Methoden, die von der Persistent-Klasse und ihren Vorfahren geerbt wurden.
Hier ist die vollständige Liste , wenn das so ist.
Erstellen Sie das erste Mitglied:
att = Attendee() att.new("")
Nach dem Ausführen dieses Codes wird in der Datenbank eine globale Datei mit dem Namen FW.AttendeeD und dem Inhalt des gerade gespeicherten Objekts wie im Screenshot angezeigt:

Nach dem Speichern hat dieses Objekt eine eigene ID (mit der Nummer 1). Daher können Sie es mit folgender ID in unser Programm laden:
att = Attendee() att.use(1) print (att.att.get("name"))
Und jetzt, da Sie die ID wieder kennen, können Sie das Objekt bei Bedarf aus der Teilnehmerdatenbank löschen:
att = Attendee() att.use(1) att.clean()
Überprüfen Sie nach dem Ausführen dieses Beispiels, ob der Datensatz über das Objekt im globalen Bereich verschwinden soll. Obwohl die heruntergeladenen Daten immer noch im Speicher Ihres Objekts verbleiben, bis das Programm beendet wird.
Machen wir den nächsten Schritt. Erstellen Sie die tatsächlichen Ereignisdatensätze.
Die Struktur der Klasse ist für das Klassenmitglied fast dieselbe wie oben. Am wichtigsten ist, dass eine Methode zum Hinzufügen von Teilnehmern zur Teilnehmerliste für diese Veranstaltung hinzugefügt wurde. AddAttendee (att).
Wir versuchen, einen Objektdatensatz über ein neues Ereignis zu erstellen und in der Datenbank zu speichern:
haJS = Event() haJS.new("haJS", " ", "2019-01-19")
Es sollte ungefähr so aussehen (beachten Sie, dass das Datum automatisch in das ObjectScript-Format konvertiert wird und beim Zurückladen in das Python-Objekt zum ursprünglichen Format zurückkehrt):

Es bleibt, den Teilnehmer zur Veranstaltung hinzuzufügen:
Diese Beispiele zeigen also, dass es nicht notwendig ist, gleichzeitig über Ihr Datenmodell und sein tabellarisches Speicherschema nachzudenken. Sie können offensichtlichere Tools für Ihre Aufgaben verwenden.
Detaillierte Anweisungen zum Verbinden und Verwenden von Caché mit Python und anderen Sprachen finden Sie immer
in der Dokumentation und im InterSystems-Entwickler-Community-Portal. Dies sind nicht weniger als 5.000 Mitglieder von
community.intersystems.comHilfe: InterSystems Caché Multimodell DBMS bleibt der ständige Weltmarktführer bei Objektdatenbanken
