AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Datendefinition der DB im Programm prüfen
Thema durchsuchen
Ansicht
Themen-Optionen

Datendefinition der DB im Programm prüfen

Ein Thema von Hobbycoder · begonnen am 8. Sep 2018 · letzter Beitrag vom 10. Sep 2018
Antwort Antwort
Seite 1 von 3  1 23      
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#1

Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 10:01
Datenbank: MySQL • Version: 5.6 • Zugriff über: UniDAC
ich brauch mal Anregungen von euch.

Zu einem Programm gehört eine DB, die sich mit neuen Version des Programms erweitert/verändert. Passiert ja schon mal

Ich möchte beim Programm start die DB überprüfen, ob alle Tabellen vorhanden sind oder welche gelöscht werden können, und ob alle Felder korrekt sind oder verändert werden müssen. Das ist vom Prinzip her ein Problem, das mach ich schon seit Jahren in einer Anwendung und läuft perfekt.
Nun wird die Anwendung aber komplett neu aufgebaut (es gibt verschiedene Gründe dafür, die aber mit der Frage nichts zu tun haben), und ich mache mir erneut Gedanken darüber, wie ich das elegant lösen kann.

Ich will also meiner Anwendung Informationen über die Datenbankstruktur mitgeben. Entweder als Datei, als Konstanten oder als Resource. Nur über die Struktur mache ich mir noch Gedanken.

Ich möchte folgende Fälle integrieren können:
  • Hinzufügen von Tabellen
  • Umbennen von Tabellen
  • Löschen von Tabellen
  • Hinzufügen von Feldern
  • Umbennen von Feldern
  • Löschen von Feldern
  • Ändern von Datentyp, Länge, Defaultwert, Attribute von Feldern
  • Datenmanupulation z.B. Zusammensetzen oder Aufteile von Daten
  • Erstellen/Löschen/Ändern von Indizes

Vielleicht gibt es für sowas ja schon was schickes, was ich da Verwenden kann.

Zur Zeit sind meine Überlegungen bei einem einfachen Textformat.
z.B so:

Code:
+Table user
+Table config
-Table users
/Table MA Mitarbeiter

+Field user ID Int 0 0 * * ""
+Field user Name varchar 100 0 - * ""
-Field user Username
/Field user VName varchar 100 0 - * "" > Vorname varchar 200 0 - * ""

+Index user ID,Name
+ für Hinzufügen, - für Löschen und / für Ändern. Dahinter jeweils Information um was für ein Objekt es sich handelt und danach dann die entsprechenden Definitionnen.

Nur bevor ich mir jetzt die Arbeit mache das umzusetzen, will ich noch mal schauen, ob das nicht besser geht.
Natürlich habe ich auch darüber nachgedacht, DDL zu verwenden. Aber ich möchte das nicht direkt an den SQL-Server schicken und dem das überlassen, sondern über mein Programm laufen zu lassen und eine Interaktion mit dem Benutzer zu ermögliche.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.387 Beiträge
 
Delphi 12 Athens
 
#2

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 10:18
Moin...

Ich finde es ist besser, im Programm ein Differenzscript (SQL) auf die DB loszulassen. In der DB muß die aktuelle DB Version stehen (Tabelle). Der Updater liest die Versionstabelle aus und führt die Scripte in der Reihenfolge bis zur aktuellen Version aus.
...Fertsch.
Zitat:
Interaktion mit dem Benutzer zu ermögliche
...beim Datenbankupdate ist das keine gute Idee.

Geändert von haentschman ( 8. Sep 2018 um 10:21 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.442 Beiträge
 
Delphi 12 Athens
 
#3

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 10:26
Zitat:
Interaktion mit dem Benutzer zu ermögliche
...beim Datenbankupdate ist das keine gute Idee.
Das kommt auf den Anwendungsfall an. Es kann ja durchaus vorkommen, daß nicht alle Clients das Programm-Update gleichzeitig einspielen. Wenn das Update nun ungefragt die Datenbank hochzieht, funktionieren die anderen Clients nicht mehr. Es soll Szenarien geben, wo das nicht gewünscht oder sogar nicht gewollt ist. Dann muss die neue Programmversion auch mit der alten Struktur arbeiten können (wenn auch eingeschränkt) und das Update wird erst dann gezielt angestoßen, wenn alle Clients auf dem neuen Stand sind.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#4

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 10:34
Moin...

Ich finde es ist besser, im Programm ein Differenzscript (SQL) auf die DB loszulassen. In der DB muß die aktuelle DB Version stehen (Tabelle). Der Updater liest die Versionstabelle aus und führt die Scripte in der Reihenfolge bis zur aktuellen Version aus.
...Fertsch.
Zitat:
Interaktion mit dem Benutzer zu ermögliche
...beim Datenbankupdate ist das keine gute Idee.
Mein Problem dabei ist, wenn auch nur ein Script dazwischen fehlt, das das schnell in die Hose. Und auch die Scripte muss ich ja irgendwie liefern oder im Programm hinterlegen.

Deswegen möchte ich ja einen Soll-Stand mit einem Ist-Stand vergleichen um dann gezielt nur die Änderungen auszuführen.
Was ich geschrieben habe mit dem Ändern von Tabellennamen oder Feld-Definitionen, das kommt eher seltener vor (Kann aber, und daher will ich das gleich vorsehen).

Interaktion kann auch bedeuten: Detaillierte Fortschrittsanzeige, oder z.B. bei Datenmanipulation die Frage: Jetzt gleich oder später nochmal nachfragen o.ä.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.

Geändert von Hobbycoder ( 8. Sep 2018 um 10:36 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jfheins
jfheins

Registriert seit: 10. Jun 2004
Ort: Garching (TUM)
4.579 Beiträge
 
#5

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 12:04
Mein Problem dabei ist, wenn auch nur ein Script dazwischen fehlt, das das schnell in die Hose. Und auch die Scripte muss ich ja irgendwie liefern oder im Programm hinterlegen.
Ja, die musst du mitliefern uns nein, natürlich darf da Keines fehlen. Aber: In den Update-Skripten (Migrationen) kannst du gleichzeitig auch die Daten migrieren!

Zitat:
Deswegen möchte ich ja einen Soll-Stand mit einem Ist-Stand vergleichen um dann gezielt nur die Änderungen auszuführen.
Was ich geschrieben habe mit dem Ändern von Tabellennamen oder Feld-Definitionen, das kommt eher seltener vor (Kann aber, und daher will ich das gleich vorsehen).
Hier klappt das dann nicht so gut, weil du von allen x Vorgängerversionen in der Lage sein müsstest, die Daten zu migrieren. Wenn du das richtig machen willst, wird der Aufwand immer größer!

Habe mal ein Projekt mit Entity Framework 6 und Migrationen gemacht, da hat das super funktioniert. Falls man eine Relation von 1:1 zu 1:n gewachsen ist: Neue Tabelle anlegen, SQL Befehl um die Daten zu kopieren und alte Tabelle anpassen. Ist eine Migration und man kann auch eine Rückmigration machen, wenn man die Funktion auch befüllt
  Mit Zitat antworten Zitat
WiPhi

Registriert seit: 19. Feb 2015
90 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 12:23
Evtl. wäre ein ORM Mapper was für dich? Damit könntest du die Strukturen via Objektattribute bestimmen. Das System kann dann die Struktur deiner Objekte auf die DB mappen und ggf. die Datenbankstruktur anpassen.

https://www.tmssoftware.com/site/aurelius.asp
https://bitbucket.org/soundvibe/marshmallow/wiki/Home

und natürlich einige weitere, aber das sind die, die ich bisher getestet habe.

Aurelius läst sich meiner Meinung nach besser an bestehende Datenbanken anpassen. Die Zugriffe funktionieren performant. Sping4D ist OpenSource, hat aber nicht so viele Möglichkeiten wie Aurelius. Aber es wird stetig an beiden ORMs weitergearbeitet (mein Eindruck) und immer wieder verbessert.
Wer sucht, der findet. Wer länger sucht, findet mehr.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#7

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 12:57
Deswegen möchte ich ja einen Soll-Stand mit einem Ist-Stand vergleichen um dann gezielt nur die Änderungen auszuführen.
Ich finde den Abschnitt sehr wesentlich.
Man braucht eine definierte Zielvorgabe. Das wäre die einzig sinnvolle Grundlage für alle Änderungsvorgänge. Für die Vorgabe kann man verschiedene Möglichkeiten nutzen, z.B. ein leeres DM Script, ggF. mit teilweise gefüllten Konfigurationsdaten (Default Customization)
Dann kann es diese Zielvorgabe auch in abstrakter Form geben, also bspw. eine Versionstabelle, die modulweise die vorhandenen Versionen anzeigt plus mögliche Upgrades/Upgrade Pfade mit statischen Scripten je Version.

Nebenbei: Kannst Du sicherstellen, dass ein Istzustand nicht vom Nutzer verfremdet wurde?

Migration:
Hier wird ja klassisch am lebenden Objekt gearbeitet. (Oder gern auf einer Staging Kopie, ..)
Als Alternative kann man auch überlegen, ein komplett neues System hochzuziehen. Das bietet sich vielleicht bei starker Restrukturierung an. Programmupdates, Neuerungen sind ja oft einfach Erweiterungen, gern abwärtskompatibel. Deine Beschreibung der Änderungen klingt aber etwas radikaler, daher ist es vielleicht hilfreich, nicht das Altsystem zu verändern, sondern neu aufsetzen und Altdaten rüberziehen. Das kann man notfalls solange machen, bis es funktioniert- ohne das Altsystem abzuschießen, es wäre damit jederzeit verfügbar, falls eine Migration fehlschlägt.

Diese Variante hätte den Vorteil, dass das alte System weiterlaufen könnte / ausgeschlichen werden kann, wenn nötig. Notfalls könnte sogar live auf alt und neu gearbeitet werden. Das neue System hätte dann Views ins alte System. Aber das macht man natürlich nicht ohne Not.

Ein ganz neues System aufzusetzen hat neben diversen Vorteilen allerdings den Nachteil, dass mindestens für den Migrationszeitraum / Parallelbetrieb die DB Ressourcen doppelt vorhanden sein müssen. (Was sie allerdings häufig sowieso sind in Form von Hot Standby usw. Systemen)

Was ist es überhaupt für ein System? Lokale Anwendung (ala Musikdatenbank , .. ) oder eher eine Firmensoftware?
Gruß, Jo
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#8

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 13:56
Habe mal ein Projekt mit Entity Framework 6 und Migrationen gemacht, da hat das super funktioniert. Falls man eine Relation von 1:1 zu 1:n gewachsen ist: Neue Tabelle anlegen, SQL Befehl um die Daten zu kopieren und alte Tabelle anpassen. Ist eine Migration und man kann auch eine Rückmigration machen, wenn man die Funktion auch befüllt
Hab mir mal ein Video dazu angesehen. Sicherlich ein tolles Tool. Aber für meine Zwecke doch zu Aufwendig. Ich ja von MS, kann das auch mit MySQL oder Firebird umgehen?

Evtl. wäre ein ORM Mapper was für dich? Damit könntest du die Strukturen via Objektattribute bestimmen. Das System kann dann die Struktur deiner Objekte auf die DB mappen und ggf. die Datenbankstruktur anpassen.

https://www.tmssoftware.com/site/aurelius.asp
https://bitbucket.org/soundvibe/marshmallow/wiki/Home

und natürlich einige weitere, aber das sind die, die ich bisher getestet habe.

Aurelius läst sich meiner Meinung nach besser an bestehende Datenbanken anpassen. Die Zugriffe funktionieren performant. Sping4D ist OpenSource, hat aber nicht so viele Möglichkeiten wie Aurelius. Aber es wird stetig an beiden ORMs weitergearbeitet (mein Eindruck) und immer wieder verbessert.
Danke für die Links. Aurelius kannte ich schon, das andere nicht. Ich werde mir das mal genauer anschauen. Allerdings bin ich gerade eher "weg von Third-Party" eingestellt

Deswegen möchte ich ja einen Soll-Stand mit einem Ist-Stand vergleichen um dann gezielt nur die Änderungen auszuführen.
Ich finde den Abschnitt sehr wesentlich.
Man braucht eine definierte Zielvorgabe. Das wäre die einzig sinnvolle Grundlage für alle Änderungsvorgänge. Für die Vorgabe kann man verschiedene Möglichkeiten nutzen, z.B. ein leeres DM Script, ggF. mit teilweise gefüllten Konfigurationsdaten (Default Customization)
Dann kann es diese Zielvorgabe auch in abstrakter Form geben, also bspw. eine Versionstabelle, die modulweise die vorhandenen Versionen anzeigt plus mögliche Upgrades/Upgrade Pfade mit statischen Scripten je Version.

Nebenbei: Kannst Du sicherstellen, dass ein Istzustand nicht vom Nutzer verfremdet wurde?

Migration:
Hier wird ja klassisch am lebenden Objekt gearbeitet. (Oder gern auf einer Staging Kopie, ..)
Als Alternative kann man auch überlegen, ein komplett neues System hochzuziehen. Das bietet sich vielleicht bei starker Restrukturierung an. Programmupdates, Neuerungen sind ja oft einfach Erweiterungen, gern abwärtskompatibel. Deine Beschreibung der Änderungen klingt aber etwas radikaler, daher ist es vielleicht hilfreich, nicht das Altsystem zu verändern, sondern neu aufsetzen und Altdaten rüberziehen. Das kann man notfalls solange machen, bis es funktioniert- ohne das Altsystem abzuschießen, es wäre damit jederzeit verfügbar, falls eine Migration fehlschlägt.

Diese Variante hätte den Vorteil, dass das alte System weiterlaufen könnte / ausgeschlichen werden kann, wenn nötig. Notfalls könnte sogar live auf alt und neu gearbeitet werden. Das neue System hätte dann Views ins alte System. Aber das macht man natürlich nicht ohne Not.

Ein ganz neues System aufzusetzen hat neben diversen Vorteilen allerdings den Nachteil, dass mindestens für den Migrationszeitraum / Parallelbetrieb die DB Ressourcen doppelt vorhanden sein müssen. (Was sie allerdings häufig sowieso sind in Form von Hot Standby usw. Systemen)

Was ist es überhaupt für ein System? Lokale Anwendung (ala Musikdatenbank , .. ) oder eher eine Firmensoftware?
Die Zielvorgabe ist immer der Stand der neuesten Programmversion.

Die grundsätzlich DB-Struktur steht fest und wird sich auch nicht wesentlich verändern. Mit dieser Struktur läuft das Programm seit mehr als 12 Jahren.
Es ist noch unter D7 geschrieben und beinhaltet einige Fremdkomponenten. Das, und die Tatsache, dass es über die Jahre an vielen Ecken "angestückelt" wurde, macht eine direkte Übernahme sehr Aufwendig. Auch sollen alle Fremdkomponenten durch eigene Komponenten ersetzt werden. Einzig ein paar Jedi-Komponenten, und die DB-Komponente sollen weiterhin Third-Party bleiben. Deswegen habe ich mich entschlossen, es von Grund auf neu zu schreiben. Die DB-Struktur soll aber im wesentlichen erhalten bleiben.

Für die Neuentwicklung könnte ich die DB auch von Hand anlegen und jeweils erweitern. Und vor Auslieferung wird auch ein ausgiebiger Migrationstest stattfinden, so dass alle Daten aus der bisherigen Struktur übernommen werden können.

Allerdings wird es auch nach Fertigstellung eine Weiterentwicklung geben. Und da geht es letztlich oft nur um Kleinigkeiten z.B: ein Datenfeld ist zu klein, ein Datentyp wird geändert, weil er sich so besser verarbeiten lässt, usw. Und natürlich wenn gänzlich neue Funktionen hinzukommen auch mal ein neue Tabelle.
Das soll aber so geschehen, wie es auch bisher ist, dass der Kunde eben die neue Version herunterladen kann, und beim ersten Start die DB im Programm angepasst wird (solche Dinge wie Update nur wenn keine anderen Clients laufen, und Programmstart verhindern wenn DB-Update läuft, sind bereits berücksichtigt). So war es auch die letzt 12 Jahre und so sollte es auch im neuen Programm laufen.

Das ein Kunde die DB-Struktur verändert kann ich nahezu ausschließen. Zwar nicht in letzter Konsequenz, aber wer mutwillig rumspielt und manipuliert hat halt Pech. Dafür gibt's ja Datensicherungen.

Ich möchte nun den Aufwand für mich relativ gering halten und auch dafür sorgen, dass alle Vorgänge nahezu automatisch ablaufen. Aber es sind mittlerweile ca 70 Tabellen. Also kommt schon etwas zusammen.
Ich muss mir das alles noch ein wenig durch den Kopf gehen lassen.
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#9

AW: Datendefinition der DB im Programm prüfen

  Alt 8. Sep 2018, 16:20
<Schrott geschrieben, hab Dich mit Codehunter verwechselt>
.. welcher Versionsstand beim Kunden vorliegt und folglich, welche Alterscripte alle laufen müssten.
Da ist es dann schon spannend, nach einer -wie auch immer gearteten- Analyse, zu einem von n bekannten Ausgangszuständen zu kommen (Änderungen durch den Kunden selbst gibt es ja praktisch nicht).
Wenn es als n Ausganszustände gibt und 1 Zielzustand gibt, gibt es n-1 Alterscripte, die haargenau festgelegt sind, oder?
Wenn Du keine explizite Metainfo über die vorliegende Version gibt, reicht es evtl. anhand von Spaltenanalysen "Fingerabrücke" festzustellen, die den Stand wiedergeben.
Man spart sich also eine mglw. unsaubere Analyse der DDL und Differenz Script Generierung und baut im Labor die notwendigen, definierten, festen Alterscripte.
Dabei kann man dann noch überlegen, ob man (bei größeren Datenbewegungen) einige der Zwischenskripte zusammenfasst, um größere Sprünge in einem zu ermöglichen, also ganz alte Version in 2 Schritten auf aktuell, statt in 11 Schritten.

Interessant finde ich hier bei Firebird, wie es mit impliziten Commits (durch DDL) aussieht. Das macht jedes System anders und wenn man nicht Acht gibt, ist -zumindest bei unvorhergesehenen Ausgangslagen- das Kind schnell in den Brunnen gefallen.
Gruß, Jo

Geändert von jobo ( 8. Sep 2018 um 18:33 Uhr)
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.201 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Datendefinition der DB im Programm prüfen

  Alt 10. Sep 2018, 08:24
Bei uns ist das so gelöst + das klappt gut:
- Es gibt in der Software eine Konstante DB_VERSION, zB 12
- Es gibt weiter eine Klasse, die Änderungsscripts auf die DB loslassen kann. Die Änderungsscripts sind an eine DB-Version gebunden + vergleichen diese Version mit der Konstanten. So kann die Klasse erkennen, welche Scripts ausgeführt werden müssen und schreiben die DB Version in die Datenbank. An der Stelle können auch Datenänderungen durchgeführt werden, wenn nötig. Weil die Klasse zusätzlich auch eine Info in der DB ablegt, kann man sich dann versionsbezogen eine History ansehen.
- Über die DB_VERSION kann der Client abgleichen, ob die DB-Version der DB mit seiner eigenen übereinstimmt. Wenn nicht --> Meldung bzw Ende.
- In Multiuser-Umgebung funktioniert das auch - der erste Client updatet die DB, uns für die anderen passt es dann schon.
- Bei der Auslieferung der Software stimmten die beiden DB Versionen natürlich überein + ab dann funktioniert obiges Schema.

Aurelius hat einen automatischen Strukturabgleich, aber der ergänzt nur + löscht keine Felder bzw migriert Daten.

Und: Wir haben da gleiche Schema auch für reine Datenänderungen ohne Strukturänderungen (zB Umkodieren etc). Alles, was nur 1x gemacht werden soll, kann so abgebildet werden.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:54 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz