Frage bzgl. shell script: JSON in DB speichern

haunt

Lieutenant
Registriert
Juni 2010
Beiträge
584
Moin zusammen,
ich bin kein richtiger Programmierer oder Linux Admin und daher bräuchte ich mal einen Rat. Ich muss Daten welche ich über ein JSON bekomme in eine DB schreiben. Hab jetzt schon einige Zeit in Google versenkt bin mir aber nicht sicher ob mein vorhaben das Mittel der Wahl ist.

Die DB ( Maria ) soll alle 2-4 Stunden neu aufgebaut werden. Die Daten kommen wie gesagt als Json.
Ich habe jetzt erlesen, dass ich via command ein JSON textfile in die Maria DB schreiben kann, heißt ich ziehe mir das JSON als text file auf den Rechner und lese es dann in die DB ein. Ist das ein gutes Vorhaben? :-) oder gibt es besser Wege?

Bin über Hilfe dankbar.
 
Also bis vor kurzem ging das wohl noch nicht, siehe: https://stackoverflow.com/questions...son-values-inside-mysql-10-2-36-mariadb-table
Aber seit genau einem Jahr kann MariaDB das wohl: https://mariadb.com/resources/blog/using-json-in-mariadb/

Weiss jetzt zwar nicht wieso du alle 2-4 die Datenbank neu bauen möchtest, aber wird wohl seine Gründe haben. Normalerweise würdest du die Einträge einfach updaten.

Mit welcher Script-Sprache du nun das JSON verarbeitest bleibt dir überlassen und halt was auf dem Rechner verfügbar ist (bash, powershell, python, go, whatever)
 
Ist das ein privates Vorhaben bei dir oder im Unternehmen?
Gibt es auch andere Aufgaben die heufig oder regelmäßig solche Datenimporte benötigen?

Wenn ja, dann macht es vielleicht Sinn über Datenintegrationstools nachzudenken. Sowas wie Apache NiFi oder MS Integration Services oder oder.. gibt ja genug auf dem Markt. Wobei das Apache NiFi schon nicht schlecht ist.
 
@Falc410 danke, das sind genau die Einträge die ich auch gefunden habe. Scheint mein Ansatz also okay zu sein.

Bzgl. Update der Einträge, wollte ich einfach faul sein. Es sind auch nicht so viele Einträge. Ich müsste mal schauen wie ich die Updates hinbekomme. Aber zunächst die schnelle Lösung ;) Ich wüste jetzt gar nicht wie ich aus dem JSoN erkennen könnte ob updates da sind.

Code:
CREATE TABLE test (ID INT, CUSTOMER_ID INT, CUSTOMER_NAME VARCHAR(255))
WITH RECURSIVE
cte1 AS ( SELECT LOAD_FILE('C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/json.txt') jsondata ),
cte2 AS ( SELECT 1 level, CAST(jsondata AS CHAR) oneobject, jsondata

aus dem Codesauszug würde ich das einfach so machen. Quasi die json.txt in die DB laden und dann habe ich ja - meine naive Annahme - die Daten in der DB. Ich stelle dann nur den DB Zugang zur Verfügung. Wie ich das dann genau bewerkstellige, wird sich noch zeigen. Hab da mal mit Appsmith/Retool rumgespielt welche ja eine Schnittstelle zur Mariadb anbieten.

Bin mal gespannt ob das so klappt :D

edit:
ist ein Semi privates unterfangen. Ich arbeitet hier einem Freund zu, welcher damit seinen Lebensunterhalt verdient. ich nehme aber gerne die Erfahrungswerte mit
 
Das was du zitierst wird eben nicht funktionieren mit MariaDB. Auch in dem Blog-Post sieht man ja, wie du JSON übergeben kannst. Einfach die Datei reinwerfen wird nicht gehen.
Updaten kannst du wenn du feste IDs pro Datensatz hast, also einen unique primary key.

NiFi ist mMn overkill für etwas was man mit einem kleinen Bash-Script machen kann. Wie du auf die DB zugreifst hängt auch vom Script ab. Entweder über mysql binary auf dem Rechner oder über einen Connector z.B. für Python; https://dev.mysql.com/doc/connector-python/en/connector-python-example-connecting.html
 
Kannst du eventuell noch ein paar Details um das Drumherum geben? Es riecht gerade gefährlich nach einem XY-Problem. Sicherlich kann man dir nun zeigen wie du eine komplette Datenbank durch Daten aus einer JSON-Datei ersetzt, aber mit hoher Wahrscheinlichkeit ist der gesamte Ansatz schon wenig sinnvoll. Beschreibe daher nach Möglichkeit erstmal die Grundsituation und das eigentliche Ziel, aber keine Lösungsansätze.
 
Falc410 schrieb:
Das was du zitierst wird eben nicht funktionieren mit MariaDB. Auch in dem Blog-Post sieht man ja, wie du JSON übergeben kannst.
Ich wollte nur aufzeigen, dass ich die Datei dann auf Betriebssystemebene habe und dann in die DB eben "einlese". Quasi der Lösung von Akina folgen, oder eben via mysql shell. Muss mal schauen ob mein Raspi das hergibt ;)

Raijin schrieb:
Kannst du eventuell noch ein paar Details um das Drumherum geben?
Ich will hier ja keine Lösung, sondern eben nur kurz Rückfragen, ob dies der richtige Weg ist. Im Endeffekt rufe ich Daten via einer API ab und bekomme von dort bspw. ein Json. Damit soll eine DB gefüllt werden. Die Daten aus der DB werden dann über eine Homepage verarbeitet.

Die Idee war dann auch gewisse automatische Prozesse einzuarbeiten.
 
haunt schrieb:
Ich will hier ja keine Lösung, sondern eben nur kurz Rückfragen, ob dies der richtige Weg ist.
Und das kann man eben nur beurteilen, wenn man den Kontext kennt.


haunt schrieb:
Die Daten aus der DB werden dann über eine Homepage verarbeitet.
Und was ist das für eine Webseite? Programmierst du die selbst bzw. hast Zugriff darauf? Weil nur mal so: Man kann eine Webseite ggfs auch direkt mit einer JSON füttern. Da die Datenbank ja augenscheinlich so oder so alle 2-4h komplett ausgetauscht wird, ist davon auszugehen, dass die besagte Webseite ja lediglich zur Darstellung der Daten dient, korrekt? Etwaige Änderungen würden den Weg ja nicht zurück in die eigentliche Anwendung finden, da die JSON-API so wie ich das verstanden habe nur OneWay ist bzw. nur so genutzt wird.
 
  • Gefällt mir
Reaktionen: Der Lord
Also die Website habe ich selbst erstellt, korrekt. Funktioniert soweit auch. Greife direkt auf die API Schnittstelle zu, dies ist aber nicht ganz so elegant wie die Lösung, dass man die Daten in der DB hat ( Stichtwort: Automatisierung ) Ich habe also alles da. PHP, jquery, html, etc.

Hinzu kommt nun, dass nun von anderer Seite auf die Daten zugegriffen werden sollen, man aber die ursprüngliche Quelle verschleiern will.
die JSON-API ist one way korrekt. Um die Daten besser nutzen zu können, müssen wir noch eigene Daten in unserer DB pflegen, daher dachte ich ist es eh sinnvoll die lokal zu replizieren.
 
haunt schrieb:
Um die Daten besser nutzen zu können, müssen wir noch eigene Daten in unserer DB pflegen, daher dachte ich ist es eh sinnvoll die lokal zu replizieren.
Hm, aber das widerspricht doch dem Konzept des kompletten Austauschs der DB über den JSON-Import, oder hab ich das falsch verstanden? Oder ersetzt du mit dem JSON-Import nur einzelne Tabellen und die übrigen Tabellen mit den ergänzten Daten bleiben erhalten? Sollte das der Fall sein, birgt das ein gewisses Risiko von Datenleichen. Wenn du beispielsweise eine Mitgliederliste via JSON importierst und ersetzt, parallel dazu aber zB eine persistente Tabelle mit Adressdaten hast, können Änderungen in der Mitgliederliste (insbesondere gelöschte Einträge) dazu führen, dass in der Adresstabelle Einträge verbleiben, die keinem Mitglied zugeordnet sind.


Ich persönlich würde eher den Weg gehen, die Daten in der JSON mit der DB zu vergleichen und ggfs ein Insert, Update oder Delete zu fahren (letzteres dann eben auch in etwaigen Referenztabellen). Das ist in meinen Augen weit weniger fehleranfällig, weil die Datenbank sonst keinerlei Kontrollmöglichkeiten über die Daten an sich mehr hat - Stichwort: Referentielle Integrität

Selbstredend ist das nur ganz allgemein gesprochen, wenn man die Struktur der Datenbank und die Natur der Daten nicht kennt. Ob das bei dir also wirklich ein Problem werden könnte, musst du selbst beurteilen.
 
ich seh da eigentlich kein Problem. Tatsächlich werde ich andere Tabellen mit Namen und ID Zugehörigkeit haben, das bleibt beim "löschen" erhalten.
Die Namen müssen eh manuell gepflegt werden und Datenleichen kann man via Zeitstempel identifizieren.

Eigentlich total easy, nur jetzt mal den import JSON in DB hinbekommen :D das mach ich jetzt quasi abends auf dem Sofa wo ich eigentlich chillen sollte... aber was tut man nicht alles für Freunde.

Den Update sehe ich als schwierig. Ich könnte mir aber tägliche Datensätze ausspucken lassen....
Eine sehr gute Idee - Danke! :D
 
kurzes Update: bin gestern kläglich gescheitert.
Habe jetzt die JSON via Skript auf dem Server, aber hochladen klappt natürlich nicht. Kann zwar die Daten manuell einklimpern, aber das ist natürlich nicht zielführend. Bei den Lösungen oben bekomme ich immer einen Syntax Fehler. der Raspbian bietet mysql shell nicht an...

Denke ich lese die nun via PHP ein. Das erscheint mir am geschicktesten.
 
War zu erwarten. Ich würde es auch über Python oder PHP machen, oder halt die Sprache mit der du dich besser auskennst. Bei PHP gibt es wie bei Python auch Connectoren. Ansonsten in Python hab ich ja schon einen Link gepostet und vorher halt mit json.loads die Datei laden und dann in die Datenbank pumpen. 20 Zeilen Code sollten mehr als ausreichend sein :)
 
kenne mich "besser" mit PHP aus. Bin mal gespannt. Gibt dazu ein schönes Youtube Video. Ich kann ja mal am Ende posten was rausgekommen ist. Mich graut es aktuell nur etwas vor den verschachtelten Arrays...
 
Moin,
so ich bin jetzt soweit die ersten Daten wurden erfolgreich in die DB gelesen. Via PHP

Code:
$link = new mysqli('$host', '$user', '$password', '$db_name');
//if connection is not successful
if (!$link) {
       die('Could not connect: ' . mysql_error());
}
//if connection is successfully
echo 'Connected successfully';
echo '\n';
$json = file_get_contents('/tmp/test.json');
$array = json_decode($json, true);

if (is_array($array)) {
        foreach ($array as $row) {
                if (is_array($row) || is_object($row))
                {
                // If yes, then foreach() will iterate over it.
                foreach ($row as $value) {
                $sql = "INSERT INTO table1 (tab1, tab2, tab3)  VALUES ('".$value['tabf1']."',  '".$value['tabf2']."', '".$value['tabf3']."')";
                $link->query($sql);
                $ZCOUNT = count($value['lastEvents']);
               
                for ($i=0 ; $i < $ZCOUNT; $i++){
                       
                        $sql2 = "INSERT into table2 (stringValue, dataType) values ('". $value['tabf3'][$i]['stringValue']."', '".$value['tabf3'][$i]['dataType']."')";
                        $link->query($sql2);
                        }
                }
        }
                echo "\n";
        }
}
mysqli_close($link);
?>

Jetzt hab ich das Problem, dass im Array noch weitere Arrays sind, Ich würde jetzt einfach die dritte Dimension in eine weitere Tabelle einlesen: table2.

Die Einträge in table2 kommen aber unsortiert.
heißt ich hätte mal an Stelle 0 bspw.

$value['tabf3'][$i]['stringValue'] = "Ich gehe in den Garten"

und einmal:

$value['tabf3'][$i]['stringValue'] ="Bratwurst"


Aktuell könnten 74 verschiedene Einträge vorkommen. Habe mal die Daten eingelesen und ein distinct count auf die tabelle ( table2 ) gemacht. Ich hätte jetzt die Lösung die einzelnen Werte abzufragen und entsprechend in die Tabelle zu speichern, da unterschiedliche Datentypen kommen. Oder reicht es wenn ich einfach alles als varchar speichere?

Hab eine Frage im Programmieren gestellt, denke mal meine Frage ist ja hier eigentlich beantwortet.
Vielen Dank für die ganzen Tipps - läuft :-)
 
Zuletzt bearbeitet:
Zurück
Oben