Daten-Setup
Einführung
Bei Netuno beginnt die Entwicklung von Anwendungen zunächst mit dem Aufbau der Datenbank, durch die Erstellung der Formulare und Felder.
Wenn im Team gearbeitet wird oder die Entwicklung der Anwendung in eine andere Umgebung übertragen werden muss, ist es notwendig, ein Backup der Datenbank zusammen mit dem Code zu erstellen.
Am Ziel muss die Datenbank dann neu konfiguriert werden, und die Anwendung kann so ausgeführt werden, wie sie an ihrem Ursprung entwickelt wurde.
Das Problem bei diesem Prozess ist der Aufwand, immer daran denken zu müssen, jedes Mal ein neues Backup zu erstellen, wenn sich etwas an der Datenbank ändert. Und je mehr Personen an der Entwicklung beteiligt sind und/oder je mehr Umgebungen es zum Veröffentlichen der Anwendung gibt, desto komplizierter wird dieser Prozess.
Um dieses Problem zu lösen, bringt Netuno ein Setup-System für Anwendungen mit, das automatisch die Struktur der Datenbank (Schema) generiert und zusätzlich ermöglicht, das Laden der Anfangsdaten über zusätzliche Skripte manuell zu programmieren.
Es ermöglicht außerdem, den Typ des Datenbankservers zu ändern, wobei gewährleistet wird, dass das Setup normal ausgeführt wird und die Anwendung ohne jegliche Probleme läuft. Das bedeutet, dass die Anwendung in H2DataBase entwickelt werden kann und mit den automatisch generierten Schemata die Datenbankverbindung der Anwendung auf PostgreSQL oder MariaDB geändert werden kann. Bei der ersten Ausführung der Anwendung auf der neuen Datenbank wird alles neu aufgebaut, unabhängig von der Änderung des Datenbankservertyps.
So kann die Datenbank vollständig geändert werden, ohne Auswirkungen auf die bereits durchgeführte Entwicklung zu haben.
Die Programmierdateien des Setup befinden sich im Anwendungsordner unter:
server/setup
Setup-Konfiguration
In den Umgebungskonfigurationen der Anwendungen, die sich hier befinden:
/apps/MEINE_APP/config/_development.json/apps/MEINE_APP/config/_production.json
können Sie das Verhalten des 'Setup' über die folgenden Konfigurationen steuern:
...
"setup": {
"enabled": true,
"schema": {
"auto_create": true,
"execution": true
},
"scripts": {
"execution": true
}
},
...
enabled: boolean > standardmäßig true
Definiert, ob das Setup aktiv ist oder nicht, und aktiviert bzw. deaktiviert damit bei der ersten Ausführung der Anwendung die Ausführung der Daten-Setup-Operationen.
schema.auto_create: boolean > standardmäßig true
Legt fest, ob Netuno die Datenbank-Schema-Dateien generieren soll, wann immer ein Formular oder Feld erstellt oder geändert wird.
schema.execution: boolean > standardmäßig true
Steuert, ob das Schema während der Setup-Operationen ausgeführt werden soll, die bei der ersten Ausführung der Anwendung durchgeführt werden.
scripts.execution: boolean > standardmäßig true
Aktiviert oder deaktiviert die Ausführung der zusätzlichen Skripte während der Setup-Operationen, die bei der ersten Ausführung der Anwendung durchgeführt werden.
Schema
Während der Erstellung oder Änderung von Formularen und Feldern in der Netuno-Weboberfläche werden die Schema-Dateien im Setup-Ordner wie folgt generiert:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
server/setup/_schema-FORMULARNAME.js
server/setup/_schema-FORMULARNAME.ts
server/setup/_schema-FORMULARNAME.py
server/setup/_schema-FORMULARNAME.rb
server/setup/_schema-FORMULARNAME.kts
server/setup/_schema-FORMULARNAME.groovy
Dabei gibt es eine Datei _schema-*** für jedes in der Anwendung vorhandene Formular.
Diese Dateien sollten nicht manuell geändert werden, da sie automatisch von Netuno generiert werden.
Wenn Sie den Inhalt dieser Dateien ändern, werden sie bei der nächsten Schema-Generierung automatisch ersetzt, und die direkt in den Dateien vorgenommenen Änderungen gehen verloren.
Damit die automatische Generierung des Datenbank-Schemas ausgeführt wird, muss sichergestellt sein, dass die Konfiguration schema.auto_create aktiv ist und der Ordner setup innerhalb des Ordners server existiert.
Skripte
Benutzerdefinierte Skripte sind Dateien im Ordner setup, die nicht mit _ beginnen.
Das Hauptziel dieser Skripte ist es, die Daten zu laden und sicherzustellen, dass die Datenbank die für den korrekten Betrieb der Anwendung erforderlichen Mindestinformationen enthält.
Wenn die Anwendung in einer anderen Umgebung neu konfiguriert wird, wird sie automatisch mit den Anfangsdaten geladen und ist bereit für die Nutzung.
Für diese Datenladeoperationen sollten Sie die Funktionen der Ressource _db verwenden.
Die Skripte werden nach der Ausführung der Schemata in alphanumerischer Reihenfolge der Dateinamen ausgeführt, die nicht mit _ beginnen.
Den Dateinamen mit einer numerischen Sequenz zu beginnen, ist ideal, um die Ausführungsreihenfolge festzulegen; daher werden die benutzerdefinierten Skripte in der Reihenfolge der Dateinamen ausgeführt, die nicht mit
_beginnen.
Benutzerdefinierte Daten einfügen
Und um den Aufwand für Datenbankabfragen zu sparen, mit denen geprüft wird, ob ein Insert von Daten durchgeführt werden kann oder nicht, stellt Netuno die Funktion insertIfNotExists bereit.
Diese Funktion prüft, ob die Daten genau so, wie sie definiert sind, in der Datenbank vorhanden sind; wenn nicht, werden sie angelegt.
Ein Beispiel für ihre Verwendung ist das Laden der Felder Kürzel und Bezeichnung des Formulars Territoriumstyp, wobei der Tabellenname territoriumstyp lautet und die Spalten kuerzel und bezeichnung hat; dafür genügt es, die Datei mit folgendem Inhalt zu erstellen:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1001")
.set("bezeichnung", "Kontinental")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1002")
.set("bezeichnung", "Archipelagisch")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "2003")
.set("bezeichnung", "Maritim")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "3004")
.set("bezeichnung", "Luft")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1001")
.set("bezeichnung", "Kontinental")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1002")
.set("bezeichnung", "Archipelagisch")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "2003")
.set("bezeichnung", "Maritim")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "3004")
.set("bezeichnung", "Luft")
);
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1001")
.set("bezeichnung", "Kontinental")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1002")
.set("bezeichnung", "Archipelagisch")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "2003")
.set("bezeichnung", "Maritim")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "3004")
.set("bezeichnung", "Luft")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1001")
.set("bezeichnung", "Kontinental")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1002")
.set("bezeichnung", "Archipelagisch")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "2003")
.set("bezeichnung", "Maritim")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "3004")
.set("bezeichnung", "Luft")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1001")
.set("bezeichnung", "Kontinental")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1002")
.set("bezeichnung", "Archipelagisch")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "2003")
.set("bezeichnung", "Maritim")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "3004")
.set("bezeichnung", "Luft")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1001")
.set("bezeichnung", "Kontinental")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "1002")
.set("bezeichnung", "Archipelagisch")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "2003")
.set("bezeichnung", "Maritim")
)
_db.insertIfNotExists("territoriumstyp", _val.map()
.set("kuerzel", "3004")
.set("bezeichnung", "Luft")
)
Verarbeitungszyklus
Wie bereits erläutert, wird das Setup nur bei der ersten Ausführung der Anwendung ausgeführt.
Die Ausführungsreihenfolge ist:
_start- führt die Initialisierungsdatei aus, die jede Art von benutzerdefinierter Programmierung enthalten kann:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MEINE_APP/server/setup/_start.js
MEINE_APP/server/setup/_start.ts
MEINE_APP/server/setup/_start.py
MEINE_APP/server/setup/_start.rb
MEINE_APP/server/setup/_start.kts
MEINE_APP/server/setup/_start.groovy
_cleanup- führt die programmatische Entfernung von Formularen, Berichten und den jeweiligen Feldern aus:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MEINE_APP/server/setup/_cleanup.js
MEINE_APP/server/setup/_cleanup.ts
MEINE_APP/server/setup/_cleanup.py
MEINE_APP/server/setup/_cleanup.rb
MEINE_APP/server/setup/_cleanup.kts
MEINE_APP/server/setup/_cleanup.groovy
_schema-*- führt alle Skripte mit dem Präfix _schema- aus und enthält die Befehle zur Erstellung der Formulare, Berichte und der jeweiligen Felder:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MEINE_APP/server/setup/_schema-autogenerierte_struktur.jsMEINE_APP/server/setup/_schema-kategorie.jsMEINE_APP/server/setup/_schema-produkt.jsMEINE_APP/server/setup/_schema-kunde.js
MEINE_APP/server/setup/_schema-autogenerierte_struktur.tsMEINE_APP/server/setup/_schema-kategorie.tsMEINE_APP/server/setup/_schema-produkt.tsMEINE_APP/server/setup/_schema-kunde.ts
MEINE_APP/server/setup/_schema-autogenerierte_struktur.pyMEINE_APP/server/setup/_schema-kategorie.pyMEINE_APP/server/setup/_schema-produkt.pyMEINE_APP/server/setup/_schema-kunde.py
MEINE_APP/server/setup/_schema-autogenerierte_struktur.rbMEINE_APP/server/setup/_schema-kategorie.rbMEINE_APP/server/setup/_schema-produkt.rbMEINE_APP/server/setup/_schema-kunde.rb
MEINE_APP/server/setup/_schema-autogenerierte_struktur.ktsMEINE_APP/server/setup/_schema-kategorie.ktsMEINE_APP/server/setup/_schema-produkt.ktsMEINE_APP/server/setup/_schema-kunde.kts
MEINE_APP/server/setup/_schema-autogenerierte_struktur.groovyMEINE_APP/server/setup/_schema-kategorie.groovyMEINE_APP/server/setup/_schema-produkt.groovyMEINE_APP/server/setup/_schema-kunde.groovy
001-weitere_skripte- führt die benutzerdefinierten Skript-Dateien aus; dies sind alle Dateien, die nicht mit_beginnen und die wahrscheinlich die erforderlichen Inserts der Anfangsdaten oder andere benutzerdefinierte Entwicklungen enthalten, zum Beispiel:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MEINE_APP/server/setup/001-benutzerdefinierte_daten_einfuegen.jsMEINE_APP/server/setup/002-kategorie.jsMEINE_APP/server/setup/003-produkt.jsMEINE_APP/server/setup/004-kunde.js
MEINE_APP/server/setup/001-benutzerdefinierte_daten_einfuegen.tsMEINE_APP/server/setup/002-kategorie.tsMEINE_APP/server/setup/003-produkt.tsMEINE_APP/server/setup/004-kunde.ts
MEINE_APP/server/setup/001-benutzerdefinierte_daten_einfuegen.pyMEINE_APP/server/setup/002-kategorie.pyMEINE_APP/server/setup/003-produkt.pyMEINE_APP/server/setup/004-kunde.py
MEINE_APP/server/setup/001-benutzerdefinierte_daten_einfuegen.rbMEINE_APP/server/setup/002-kategorie.rbMEINE_APP/server/setup/003-produkt.rbMEINE_APP/server/setup/004-kunde.rb
MEINE_APP/server/setup/001-benutzerdefinierte_daten_einfuegen.ktsMEINE_APP/server/setup/002-kategorie.ktsMEINE_APP/server/setup/003-produkt.ktsMEINE_APP/server/setup/004-kunde.kts
MEINE_APP/server/setup/001-benutzerdefinierte_daten_einfuegen.groovyMEINE_APP/server/setup/002-kategorie.groovyMEINE_APP/server/setup/003-produkt.groovyMEINE_APP/server/setup/004-kunde.groovy
- _end - führt die Abschlussdatei aus, die jede Art von benutzerdefinierter Programmierung enthalten kann:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MEINE_APP/server/setup/_end.js
MEINE_APP/server/setup/_end.ts
MEINE_APP/server/setup/_end.py
MEINE_APP/server/setup/_end.rb
MEINE_APP/server/setup/_end.kts
MEINE_APP/server/setup/_end.groovy
Das heißt, es ist erlaubt, benutzerdefinierten Code in den Start- und End-Skripten zu erstellen, um einige Operationen durchzuführen, die sinnvollerweise vor dem Setup oder auch nach dessen Abschluss ausgeführt werden.
Es sei betont, dass dieser Verarbeitungszyklus immer dann ausgeführt wird, wenn die Anwendung zum ersten Mal ausgeführt wird; deshalb ist es notwendig, vor dem Anlegen der Daten deren Existenz zu prüfen.
Stellen Sie sicher, dass die folgenden Konfigurationen der Umgebung aktiv sind, damit dieser Prozess in den Dateien MEINE_APP/config/_development.json oder MEINE_APP/config/_production.json je nach Umgebung ausgeführt werden kann:
-
Aktiviert oder deaktiviert vollständig die Ausführung jeglicher Setup-Operation:
setup.enabled = true|false -
Aktiviert oder deaktiviert die Ausführung der _schemas-:
setup.schema.execution = true|false -
Aktiviert oder deaktiviert die Ausführung der Skripte:
setup.scripts.execution = true|false
Bereinigung
Um die Entfernung von Formularen und Feldern zu programmieren, sollten wir das Skript _cleanup.js verwenden; dies stellt sicher, dass in allen Umgebungen, die die Projektdateien synchronisieren, bei der Ausführung des Setups die Struktur entfernt wird, falls sie existiert.
Beispiel für das Bereinigungsskript:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
// Entfernt das Formular zone:
_form.dropIfExists("zone");
// Entfernt das Feld unterbereich_id aus dem Formular bereich:
_form.dropFieldIfExists("bereich", "unterbereich_id");
// Entfernt das Formular zone:
_form.dropIfExists("zone");
// Entfernt das Feld unterbereich_id aus dem Formular bereich:
_form.dropFieldIfExists("bereich", "unterbereich_id");
# Entfernt das Formular zone:
_form.dropIfExists("zone")
# Entfernt das Feld unterbereich_id aus dem Formular bereich:
_form.dropFieldIfExists("bereich", "unterbereich_id")
# Entfernt das Formular zone:
_form.dropIfExists("zone")
# Entfernt das Feld unterbereich_id aus dem Formular bereich:
_form.dropFieldIfExists("bereich", "unterbereich_id")
// Entfernt das Formular zone:
_form.dropIfExists("zone")
// Entfernt das Feld unterbereich_id aus dem Formular bereich:
_form.dropFieldIfExists("bereich", "unterbereich_id")
// Entfernt das Formular zone:
_form.dropIfExists("zone")
// Entfernt das Feld unterbereich_id aus dem Formular bereich:
_form.dropFieldIfExists("bereich", "unterbereich_id")
DBML
Immer wenn Netuno das Daten-Setup ausführt, wird die Datei generiert:
server/setup/_db-schema.dbml
Dies ist die Datei mit der gesamten Datenstruktur, die mit Künstlicher Intelligenz verwendet werden kann.
Anhand des Inhalts des DBML versteht die Künstliche Intelligenz die Datenstruktur und kann präzise SQL-Abfragen generieren.
Versuchen Sie, diese Datei als Anhang im Prompt zu verwenden und darum zu bitten, komplexe SQL-Abfragen zu generieren; Sie werden gute Ergebnisse erzielen.
Fazit
Der Setup-Prozess der Anwendungen in Netuno hat als Hauptfunktionen:
- _schema-: generiert automatisch die gesamte Struktur der Formulare und Berichte mit ihren jeweiligen Feldern, die die Kohärenz der Datenbankstruktur der Anwendung gewährleisten, insbesondere wenn die Anwendung mit einer neuen leeren Datenbank ausgeführt wird.
- Skripte: führen Datenbankoperationen aus, um sicherzustellen, dass die Anwendung die erforderlichen Daten bereits geladen enthält, wann immer sie zum ersten Mal ausgeführt wird.
Auf diese Weise ermöglicht Netuno, dass Anwendungen in neuen Umgebungen funktionieren, selbst wenn der Datenbanktyp geändert wird, und gewährleistet den korrekten Betrieb der Anwendung, ohne dass Backups und Restores der Datenbanken durchgeführt werden müssen.
Zusätzlich wird ermöglicht, dass der gesamte automatisch und manuell generierte Konfigurationscode beispielsweise mit GIT versioniert wird.