Logfile in eine MSSQL Datenbank einlesen
Dann musst du das so definieren, indem du einen UNIQUE-Constraint einfuehrst, der alle Spalten umfasst. Danach solltest du zumindest einen Fehler bekommen, wenn du versuchst, die gleiche Zeile zweimal anzulegen. Und dann geht's weiter, du musst dein Skript so umschreiben, dass es entweder alles zeilenweise einfueght, committet oder zurueckrollt, oder du versuchst dich an Mechanismen wie sie hier https://stackoverflow.com/questions/209 ... -not-exist beschrieben werden.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Also müsste man jeder Zeile das Attribut, "unique" geben, damit es eine Fehlermeldung gibt, auf grund derer man dann die eintragung dieser Zeile skippen kann?
@fredvonfat: nein. Du mußt alle Felder zusammen einen UNIQUE-Constraint geben, weil nur alle Felder zusammen eindeutig sein müssen.
Inzwischen hast Du es ja geschafft, dass Fehlerzeilen und normale Zeilen das gleiche Schema teilen, dann ist aber eine Unterscheidung zwischen Error und Main unsinnig.
Wenn man garantieren kann, dass nachträglich keine weiteren Einträge hinzukommen, wäre das einfachste Kriterium das Datum, so dass man alle Einträge skippen kann, die älter sind als der neuste Eintrag in der Datenbank.
Inzwischen hast Du es ja geschafft, dass Fehlerzeilen und normale Zeilen das gleiche Schema teilen, dann ist aber eine Unterscheidung zwischen Error und Main unsinnig.
Wenn man garantieren kann, dass nachträglich keine weiteren Einträge hinzukommen, wäre das einfachste Kriterium das Datum, so dass man alle Einträge skippen kann, die älter sind als der neuste Eintrag in der Datenbank.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Ja, daran hatte ich auch schon gedacht.nzwischen hast Du es ja geschafft, dass Fehlerzeilen und normale Zeilen das gleiche Schema teilen, dann ist aber eine Unterscheidung zwischen Error und Main unsinnig.
Würde es reichen, wenn ich "def insert_entries" anpasse? In "def parse_log" benötige ich die Unterscheidung ja noch.
Leider reicht das nicht aus, da der Zeitstempel durchaus gleich sein kann, allerdings ist dann mindestens eines der anderen Felder anders.Wenn man garantieren kann, dass nachträglich keine weiteren Einträge hinzukommen, wäre das einfachste Kriterium das Datum, so dass man alle Einträge skippen kann, die älter sind als der neuste Eintrag in der Datenbank.
Auszuschließen ist, dass Zeit und Rufnummer bei zwei aufeinander folgenden Einträgen gleich ist.
Dann eben der UNIQUE-constraint ueber die notwendigen Spalten. https://stackoverflow.com/questions/347 ... le-columns
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Nach einigem Experimentieren stellt sich heraus, dass es tatsächlich sämtliche Konstellationen gibt, so dass ich die komplette Zeile auswerten muss....
Bei nachfolgenden Code bekomme ich
ohne Limit geht es...
Gibt es da eine alternative zu?
Bei nachfolgenden Code bekomme ich
102, b"Incorrect syntax near 'LIMIT'.DB-Lib error message 20018,
Code: Alles auswählen
with pymssql.connect(server, user, password, database) as conn:
with conn.cursor(as_dict=True) as cursor:
cursor.execute('SELECT * FROM main ORDER BY zeit LIMIT 1')
for row in cursor:
print("%s %s %s %s %s %s" %
(
row['zeit'],
row['prom'],
row['message'],
row['did'],
row['rufnummer'],
row['site']))
Gibt es da eine alternative zu?
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Den letzten Eintrag in der DB mit den logfile lines vergleichen.
Warum den letzten? Ich denke das reicht nicht, sondern es koennen mehrere pro Zeitpunkt sein? Hast du vorher doch noch extra ausgefuehrt?
Und wenn dich nur der neueste interessiert, sollte eigentlich MAX(zeit) klappen. Das gibt dann nur eine Zeile als Ergebnis.
Und wenn dich nur der neueste interessiert, sollte eigentlich MAX(zeit) klappen. Das gibt dann nur eine Zeile als Ergebnis.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Ich such irgendwie ne Lösung, so dass nicht jedes mal die komplette Tabelle untersucht werden muss. Da können im Laufe der Zeit viele hundert tausende Zeilen drin sein.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Eigentlich muss ich nur die Einträge vom gleichen Tag vergleichen, denn am nächsten tag ist es wieder ein neues logfile.....
Ich bin ja für praktische Lösungen.
Ich würde mir nach der erfolgreichen Speicherung der Daten merken, wieviele Zeilen ich aus der Log-Datei gelesen wurden, und diese beim nächsten Mal skippen.
Das mit den Constraints würde ich aber trotzdem machen (auch wenn das teuer ist) um am kleinsten Punkt ausschließen zu können, dass eine Zeile doppelt hinein rutscht.
Ich würde mir nach der erfolgreichen Speicherung der Daten merken, wieviele Zeilen ich aus der Log-Datei gelesen wurden, und diese beim nächsten Mal skippen.
Das mit den Constraints würde ich aber trotzdem machen (auch wenn das teuer ist) um am kleinsten Punkt ausschließen zu können, dass eine Zeile doppelt hinein rutscht.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Constraints hab ich schon über das SQL Management Studio eingerichtet. Das funktioniert schon.
Das mit den Zeilen merken erscheint mir eine gute Idee, die steht ja mit im logfile.
Habe nur noch keine Idee, wie das merken funktioniert.
Das mit den Zeilen merken erscheint mir eine gute Idee, die steht ja mit im logfile.
Habe nur noch keine Idee, wie das merken funktioniert.
Man könnte sie in eine Datenbank schreiben und dann nachschauen, ob die Zeilen schon drin sind
Ernsthaft: Datenbanken sind für sowas gemacht. Pragmatisch ist nicht sich irgendwelchen kruden Kriterien auszudenken, nach denen man da voreilig optimiert. Sondern die DB ihren Job machen zu lassen. Der unique constraint sollte bei voller bei voller Abfrage eigentlich auch einen Index enthalten, so das die Antwort ob die Zeile enthalten ist effizient berechnet wird.
Ernsthaft: Datenbanken sind für sowas gemacht. Pragmatisch ist nicht sich irgendwelchen kruden Kriterien auszudenken, nach denen man da voreilig optimiert. Sondern die DB ihren Job machen zu lassen. Der unique constraint sollte bei voller bei voller Abfrage eigentlich auch einen Index enthalten, so das die Antwort ob die Zeile enthalten ist effizient berechnet wird.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Danke für die super Anregungen.
Jetzt habe ich wieder viele Hausaufgaben.
Jetzt habe ich wieder viele Hausaufgaben.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Nach einmal drüber schlafen und grübeln, erscheint mir der Vorschlag von deets am einfachsten realisierbar.Dann musst du das so definieren, indem du einen UNIQUE-Constraint einfuehrst, der alle Spalten umfasst. Danach solltest du zumindest einen Fehler bekommen, wenn du versuchst, die gleiche Zeile zweimal anzulegen. Und dann geht's weiter, du musst dein Skript so umschreiben, dass es entweder alles zeilenweise einfueght, committet oder zurueckrollt,
Jedoch fiel mir dabei auf, das ich noch einige verständnisprobleme zu den funktionen habe.
main:
Hier wird "insert_entries" einmalig aufgerufen und die objekte von "parse_log" als parameter übergeben?
Ich komme darauf, weil nach der ersten Zeile gleich ein Abbruch erfolgt wenn die Eintragung dieser ein Fehler verursacht.
Oder wird try so häufig ausgeführt, bis keine Daten mehr von "parse_log" kommen und so lange nichts unerwartetes auftritt?
insert_entries:
Wo wird der Parameter "entries" definiert oder ist dieser direkt von Python gegeben?
Wenn zum start von "insert_entries", alle Objekte von "parse_log" zur Verfügung stehen, scheint diese Funktion, die Menge der Objekte zeilenweise abzuarbeiten und in die Datenbank zu übertragen.
Oder wird auch "insert_entries" so oft aufgerufen, wie erforderlich und bekommt die Objekte zeilenweise serviert?
parse_log :
1. Hier werden die Zeilen des Logfiles verarbeitet, manipuliert und gesammelt in einem Tupel bereitgestellt?
2. Oder geschieht die Bereitstellung zeilenweise und die funktion wird so oft aufgerufen wie notwendig?
Was ich hier im Forum schon gelernt habe ist, dass man eine Funktion dann definiert, wen man den entsprechenden Aufruf häufiger verwendet.
Demnach würde ich hier zu 2. tendieren. Liege ich da richtig?
Wenn "insert_entries" und "parse_log" zeilenweise liefern, dann müsste ich demnach nur in "main" eine "for-Schleife" um "try / except / else" legen und dann sollte der Vorschlag von deets realisiert sein, oder?
All diese Fragen sind wirklich absolute Grundlagen von Python. Hast du schon mal das Tutorial durchgearbeitet? Zu den Kontrollstrukturen if/for/while/try und der Definition von Funktionen und deren Aufruf steht da wirklich alles episch erklaert. Es bringt nichts, wenn du beliebig Annahmen ueber die Art und Weise wie ein Programm funktioniert triffst, und wir die dann einzeln korrigieren muessen. Und wenn du gelernt hast, wie man Funktionen erstellt und aufruft, dann frage ich mich, warum du dich fragst, woher "entries" kommt.
Das einzige, das ein bisschen fortgeschrittener ist, ist parse_log. Das ist dir aber auch schon erklaert worden, dass es sich dabei um einen generator handelt.
Das einzige, das ein bisschen fortgeschrittener ist, ist parse_log. Das ist dir aber auch schon erklaert worden, dass es sich dabei um einen generator handelt.
-
- User
- Beiträge: 51
- Registriert: Mittwoch 12. September 2018, 10:00
- Wohnort: Berlin
Ja, ich bin mir bewusst, das ich gravierende Lücken in den Grundlagen zu Python habe.
Kapitelweise hab ich mir ein paar tutorials angeschaut.
Zum Verständnis dessen hilft es mir, wenn ich anhand eines Projektes, antworten auf die entstandenen Fragen bekomme, auch wenn es nur ein ja oder nein ist, oder ein Hinweis auf Quellen für Informationen.
Manchmal stehe ich einfach auf dem Schlauch und brauche nen kleinen Schubs.
Kapitelweise hab ich mir ein paar tutorials angeschaut.
Zum Verständnis dessen hilft es mir, wenn ich anhand eines Projektes, antworten auf die entstandenen Fragen bekomme, auch wenn es nur ein ja oder nein ist, oder ein Hinweis auf Quellen für Informationen.
Manchmal stehe ich einfach auf dem Schlauch und brauche nen kleinen Schubs.
Tut mir leid, aber das geht weit ueber das Ausmass von "schubsen" hinaus, die ich hier leisten kann. Vielleicht haben andere da mehr Zeit. Viele deiner Fragen wurden uebrigens schon beantwortet, und auch Quellen genannt. Das nur am Rande.