Nabend,
ist zwar kein wirkliches Python-Problem, aber ich hoffe mal man kann mir auf die Sprünge helfen.
Ich habe eine MySQL- Datenbank aufgesetzt. Ein Python-Script wird regelmäßig aufgerufen, sucht nach neuen Daten auf der Festplatte und schreibt mir diese in die Datenbank.
Zusätzlich habe ich ein Web-Frontend das auf die Datenbank zugreift und mir die Daten darstellt.
Im großen und ganzen funktioniert das ganze schon mal. Wenn jedoch durch mein Skript neue Daten in die db geschrieben werden kann ich sie mir nicht direkt anzeigen lassen - das Webfrontend bekommt beim Abruf aus der db immer die gleichen(noch alten) Daten ausgeben.
Starte ich nun mein Frontend neu wird eine neue Verbindung zur Datenbank hergestellt. Danach kann ich auch die zuletzt eingetragenen Daten abrufen. Das gleiche funktioniert natürlich auch wenn ich die Verbindung zur db zur laufzeit einfach trenne und neu herstelle.
Die beiden Programme benutzen zur Verbindung mit der Datenbank den gleichen Benutzernamen. Alles findet direkt auf localhost statt. Die Datenbankverbindung läuft in beiden Programmen mit Python und MySQLdb.
Ich werde das Gefühl nicht los das ich irgendwas ganz einfaches übersehen habe...
mehrere Verbindungen mit MySQL
Poste doch mal ein bisschen Code von den zwei Komponenten.
An deiner Beschreibung ist mir spontan nichts Besonderes aufgefallen.
Hinweis: Größere Code-Ausschnitte bitte auslagern, z.B. http://paste.pocoo.org/
An deiner Beschreibung ist mir spontan nichts Besonderes aufgefallen.
Hinweis: Größere Code-Ausschnitte bitte auslagern, z.B. http://paste.pocoo.org/
naja, was soll ich da großartig an Code posten? Die Datenbankzugriffe mache ich über normale sql Statements.
die Verbindung wird wie in der Doku erstellt mit
die Daten werden eingetragen mit:
abgerufen wird vorerst mit:
Beide Scripte benutzen das gleiche Python-Modul für Zugriffe auf die Datenbank. Die Statements sind meiner Meinung nach auch nicht das Problem - da die Daten ja eingetragen werden und auch abgerufen werden können. Ich vermute das Problem eher bei irgendwelchen Verbindungseinstellungen oder bei irgendwelchen Einstellungen für MySQL.
Zuerst hatte ich ein fehlendes commit beim eintragen der Daten vermutet - allerdings stehen (und bleiben) die Daten ja in der Datenbank. Gibt es noch einen ähnlichen Befehl der dafür sorgt das die neu eingetragenen Daten auch an alle anderen Clients ausgeliefert werden? Eine Art Cache?
... ich hab echt keinen Plan wonach ich suchen soll
die Verbindung wird wie in der Doku erstellt mit
Code: Alles auswählen
db = MySQLdb.connect(host = "127.0.0.1",
passwd = self.cfg["DB_PASS"],
user = self.cfg["DB_USER"],
db= self.cfg["DB_NAME"],
use_unicode = True)
c = MySQLdb.cursors.DictCursor(db)
die Daten werden eingetragen mit:
Code: Alles auswählen
def insert(self, data):
self.c.execute("""INSERT INTO logdata
(timestamp, temp_sens_1, temp_sens_2, temp_sens_3, temp_sens_4, temp_sens_5,
temp_sens_6, temp_sens_7, temp_sens_8, temp_sens_9, temp_sens_10, irradiation,
pulse, digit_in, rotation_speed_1, rotation_speed_2, rotation_speed_3, rotation_speed_4,
rotation_speed_5, rotation_speed_6, rotation_speed_7, error_mask, messages, system,
pattern, heat_val_hk1, state_hk1_module, heat_val_hk2, state_hk2_module, heat_val_hk3,
state_hk3_module, heat_val_heating, state_heating, version)
VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )
""", data)
self.db.commit()
Code: Alles auswählen
def get_all(self):
self.c.execute("""SELECT * FROM logdata""")
return self.c.fetchall()
Zuerst hatte ich ein fehlendes commit beim eintragen der Daten vermutet - allerdings stehen (und bleiben) die Daten ja in der Datenbank. Gibt es noch einen ähnlichen Befehl der dafür sorgt das die neu eingetragenen Daten auch an alle anderen Clients ausgeliefert werden? Eine Art Cache?
... ich hab echt keinen Plan wonach ich suchen soll
Vielleicht hilft ja ein "FLUSH TABLE":
http://dev.mysql.com/doc/refman/5.1/en/flush.html
Aber normal müsste das auch so gehen. Wie ist denn deine Systemkonfiguration?
Testweise könntest du es auch mal mit dem normalen Cursor (anstatt diesem DictCursor versuchen) vielleicht macht der auch Probleme.
http://dev.mysql.com/doc/refman/5.1/en/flush.html
Aber normal müsste das auch so gehen. Wie ist denn deine Systemkonfiguration?
Testweise könntest du es auch mal mit dem normalen Cursor (anstatt diesem DictCursor versuchen) vielleicht macht der auch Probleme.
Code: Alles auswählen
c = db.cursor()
Ohne es getestet zu haben: Erzeuge mal den Cursor bei jedem Zugriff neu. Dieses 'self.c.blabla' sieht ganz so aus als würdest du ihn zentral vorhalten und immer wieder verwenden. Vielleicht hat der 'gebrauchte' Cursor einfach noch nicht mitbekommen, daß sich an der Tabelle was geändert hat?
ja, das ich die Verbindung zur Datenbank und auch den Cursor offen halte hätte ich wohl sagen sollen. Mein Fehler.
Das habe ich aus einem etwas älterem Webprojekt behalten und einfach angepasst. Damals hatte ich nur eine Verbindung meiner Webapplikation vorgesehen. Das war kein Problem.
Wenn ich jetzt den Cursor vor einer Abfrage neu erstelle habe ich das gleiche Verhalten wie vorher - vorerst erstelle ich vor einer Abfrage aus der db einen neue Verbindung - das finde ich aber eher suboptimal...
Ich habe auch mal die Vorschläge von ice2k3 ausprobiert - `FLUSH TABLE` hörte sich gut an. Half leider nicht wirklich weiter. Ich habe auch mal verschiedene Andere Varianten ausprobiert wie `RESET QUERY CACHE` leider alles ohne Erfolg
Das habe ich aus einem etwas älterem Webprojekt behalten und einfach angepasst. Damals hatte ich nur eine Verbindung meiner Webapplikation vorgesehen. Das war kein Problem.
Wenn ich jetzt den Cursor vor einer Abfrage neu erstelle habe ich das gleiche Verhalten wie vorher - vorerst erstelle ich vor einer Abfrage aus der db einen neue Verbindung - das finde ich aber eher suboptimal...
Ich habe auch mal die Vorschläge von ice2k3 ausprobiert - `FLUSH TABLE` hörte sich gut an. Half leider nicht wirklich weiter. Ich habe auch mal verschiedene Andere Varianten ausprobiert wie `RESET QUERY CACHE` leider alles ohne Erfolg
Hi,
ja das ist ein kleines Bottle Projekt das über mod_wsgi auf dem Apache eingebunden ist. Das läuft wie du schon richtig sagtest permanent. Das Problem tritt aber auch schon mit den normalen Enticklungsserver auf.... der wird ja auch nicht ständig gestartet
ja das ist ein kleines Bottle Projekt das über mod_wsgi auf dem Apache eingebunden ist. Das läuft wie du schon richtig sagtest permanent. Das Problem tritt aber auch schon mit den normalen Enticklungsserver auf.... der wird ja auch nicht ständig gestartet
ok, nachdem ich mich noch mal ein Wenig mit der Doku zu MySQL befasst habe habe ich mal die Speicher-Engine von InnoDB auf MyISAM umgestellt. Siehe da - es funktioniert. Da ich auch keine transaktionssichere Enginge beötige denke ich das ich das so lassen werde.
Ich kann ganz normal meine einmal erstellte Datenbankverbindung mit dem einmalig erstellten Cursor verwenden.
...muss mich wohl nur noch mal bei Gelegenheit mit den einzelnen DB- Engines auseinandersetzen und schauen was ich da noch alles nicht berücksichtigt habe...
Danke noch mal für eure Hilfe
Ich kann ganz normal meine einmal erstellte Datenbankverbindung mit dem einmalig erstellten Cursor verwenden.
...muss mich wohl nur noch mal bei Gelegenheit mit den einzelnen DB- Engines auseinandersetzen und schauen was ich da noch alles nicht berücksichtigt habe...
Danke noch mal für eure Hilfe
- noisefloor
- User
- Beiträge: 3854
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
ich benutze auch Bottle + MySQL für eine Intranet Projekt.
Ich baue jede Verbindung zur DB aber immer dann auf (und wieder ab ), wenn's nötig ist. Eine persistente Verbindugn braucht man in der Regel eher nicht. Und ich verwendet die MyISAM-Engine. Klappt alles 1A.
Wo war denn jetzt bei dir das Problem? Die persistente Verbindung oder eine falsche Nutzung von InnoDB?
Gruß, noisefloor
ich benutze auch Bottle + MySQL für eine Intranet Projekt.
Ich baue jede Verbindung zur DB aber immer dann auf (und wieder ab ), wenn's nötig ist. Eine persistente Verbindugn braucht man in der Regel eher nicht. Und ich verwendet die MyISAM-Engine. Klappt alles 1A.
Wo war denn jetzt bei dir das Problem? Die persistente Verbindung oder eine falsche Nutzung von InnoDB?
Gruß, noisefloor
hi,
das Problem `vermute` ich war die Verwendung von InnoDB in der Verbindung mit mehreren Clients die Daten in der Datenbank ändern. Ich habe mich durch einige Dokus gelesen, sicher bin ich mir noch nicht - da habe ich zu wenig Erfahrungswerte.
Für mich sieht es so aus als ob eine Transaktion noch nicht abgeschlossen war und ich noch den Zustand der Daten ausgeliefert bekam zum letzten konsistenten Zeitpunkt. Obwohl die Transaktionen eigentlich automatisch als abgeschlossen gelten sollten.
Naja - mit der MyISAM-Engine läufts rund. Keine Probleme mehr - auch meine Datenbankverbindung lasse ich bestehen und baue sie nur wieder neu auf wenn die Datenbank sie nach einem Timeout schliesst.
das Problem `vermute` ich war die Verwendung von InnoDB in der Verbindung mit mehreren Clients die Daten in der Datenbank ändern. Ich habe mich durch einige Dokus gelesen, sicher bin ich mir noch nicht - da habe ich zu wenig Erfahrungswerte.
Für mich sieht es so aus als ob eine Transaktion noch nicht abgeschlossen war und ich noch den Zustand der Daten ausgeliefert bekam zum letzten konsistenten Zeitpunkt. Obwohl die Transaktionen eigentlich automatisch als abgeschlossen gelten sollten.
Naja - mit der MyISAM-Engine läufts rund. Keine Probleme mehr - auch meine Datenbankverbindung lasse ich bestehen und baue sie nur wieder neu auf wenn die Datenbank sie nach einem Timeout schliesst.
- noisefloor
- User
- Beiträge: 3854
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
THX.
Gruß, noisefloor
Gruß, noisefloor
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Bin kein Experte in diesen Dingen. Kann es sein, das InnoDB Fehler Anzeigt, die MyISAM schlicht unterm Tisch fallen lässt? Von daher kann man evtl. nicht wirklich von "rund laufen" sprechen
Stichwort wonach ihr suchen solltet, wäre "Connection Pool" ?
Stichwort wonach ihr suchen solltet, wäre "Connection Pool" ?
- Käptn Haddock
- User
- Beiträge: 169
- Registriert: Freitag 24. März 2006, 14:27
Das eine ist transaktionssicher, das andere nicht. D.h. wenn eine Transaktion was zum Schreiben gesperrt hat, bekommt eine andere nur 'veraltete' Daten zu sehen, bzw wird blockiert, bis die erste fertig ist. Gemeinhin ist das auch so beabsichtigt, zumindest, wenn man Wert auf seine Daten legt .jens hat geschrieben:Bin kein Experte in diesen Dingen. Kann es sein, das InnoDB Fehler Anzeigt, die MyISAM schlicht unterm Tisch fallen lässt? Von daher kann man evtl. nicht wirklich von "rund laufen" sprechen
Stichwort wonach ihr suchen solltet, wäre "Connection Pool" ?
Da MyISAM sich aber nicht um Transaktionen schert, bringt es also auch keine Fehler (bin allerdings kein MySQL-Experte...)
CU Uwe
---------------------------------
have a lot of fun!
have a lot of fun!
- noisefloor
- User
- Beiträge: 3854
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Gruß, noisefloor
Nee, das ist in der Tat der Unterscheid zwischen den transaktions-sichern DB-Engines und der nicht-transaktionsabsierten MyISAM Engine. Geschrieben wird es ja immer - der Unterschied ist, wann es auch lesbar ist, ist. Warum das so ist oder ob es daran liegt, dass sich InnoDB bei persistenten Verbindungen anders verhält kann ich auch nicht sagen. Ich nehm' immer MyISAM.jens hat geschrieben:Bin kein Experte in diesen Dingen. Kann es sein, das InnoDB Fehler Anzeigt, die MyISAM schlicht unterm Tisch fallen lässt?
Gruß, noisefloor
Hi,jens hat geschrieben:Was ich meinte: Die Frage ist, ob bei MyISAM die Daten auch wirklich konsistent bleiben. Die Fehler, die bei InnoDB auftreten, sind vielleicht in Indiz dafür, das die aktuelle Lösung nicht brauchbar ist...
da nur einer von meinen beiden Clients Daten in die Datenbank schreiben wird und der andere Client ausschliesslich Daten abfragt kann ich doch auf Transaktionen verzichten. Denn der Client der Daten schreibt hat immer einen Konsistenten Datensatz vor sich.
Wie ich schon gestern geschrieben habe habe ich mit Transaktionen bisher noch keine Erfahrungen gesammelt. Ich habe bisher gedacht das meine Schnittstelle das im Hintergrund für mich erledigen würde. Falls da jemand ein kleines Beispiel mit MySQLdb hat würde ich mir das gerne mal anschauen.
Sebastian
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Grundlagen: http://wiki.python-forum.de/DB-Transaktionen
- noisefloor
- User
- Beiträge: 3854
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
@jens:
Interessant bei dem Problem hier, warum der Commit mit InnoDB nicht geschrieben wird...
Gruß, noisefloor
@jens:
Tun sie. Auch bei MyISAM wird ein Lock auf die Tabelle beim Schreiben gesetzt, d.h. es gibt keine konkurrierenden Schreibzugriffe auf die Tabelle. Außerdem bin ich mir ziemlich sicher, dass MyISAM auch ACID-konform ist, also wird "alles-oder-nichts" geschrieben.Die Frage ist, ob bei MyISAM die Daten auch wirklich konsistent bleiben.
Interessant bei dem Problem hier, warum der Commit mit InnoDB nicht geschrieben wird...
Gruß, noisefloor