sqlalchemy - Zeilen aus Query Object entfernen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Hallo,
ich will aus meinem query object mehrere Zeilen (zufällig) entfernen, bevor ich für alle Zeilen im query object ein update mache.

Nochmal als einfaches Beispiel: Ich will in den Zeilen, in denen der Vorname "Peter" ist, den Vorname in "Robert" ändern. Von den 10 Petern sollen aber nur 5 zufällige Zeilen geändert werden.

Ich versuch mich an der Problematik schon ein wenig, aber komm einfach auf keinen grünen Zweig :K
Die Ausgangssituation sieht wie folgt aus:

Code: Alles auswählen

writerRes = self.session.query(table)
writerRes = writerRes.filter(table.vorname=="Peter")
writerRes.update({"vorname": "Robert"})
Nur sollen nicht alle Peter umbenannt werden, sondern nur maximal 5.

Vielen Dank schonmal für Hilfe :wink:
Sirius3
User
Beiträge: 17762
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Trubinial Guru,

Du läßt Dir alle Einträge geben und suchst Dir 5 davon aus, die Du dann einzeln updatest.

Grüße
Sirius
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

@Sirius3: Das wollte ich eigentlich umgehen, da es ne Menge Einträge sind und ich Performance Einbußen befürchte.
Gibt es nicht noch andere Möglichkeiten?
Sirius3
User
Beiträge: 17762
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn es Dir um Performance geht, dann handelt es sich wohl nicht nur um einen Test.

Aber dann mußt Du mir doch genau den Sinn dieser Aktion erklären, weil es bestimmt
eine andere Lösung gibt, »zufällig« den Query zu ändern.
BlackJack

@Trubinial Guru: Leistungseinbussen *befürchten* ist immer so eine Sache. Bevor Du Zeit in eine Lösung versenkst, die etwas macht wofür SQL meiner Meinung nach nicht geeignet ist, solltest Du eventuell erst einmal den einfachen offensichtlichen Weg umsetzen und *messen* ob das überhaupt zu langsam ist.
Trubinial Guru
User
Beiträge: 117
Registriert: Dienstag 7. April 2009, 13:40

Naja das vereinfachte Beispiel mit Peter und Robert modelliert die Aktion eigentlich schon sehr gut, nur dass es um mehr Daten geht und die Performance ist dabei wichtig, da es gut sein kann, dass die Aktion mehrmals hintereinander ausgeführt werden muss und die Oberfläche (Liste) schnellstmöglich aktualisiert werden sollte -> Wartezeiten machen sich da sofort bemerkbar. Ich hatte es bis jetzt so, dass ich dann das Update jedem einzeln ausgewählten Eintrag ausgeführt habe (wie du es vorgeschlagen hast) - aber das war einfach zu langsam. Bei 1200 Einträgen waren das schon mal 20 Sekunden in denen das Programm stillstand.

@BlackJack: Leider muss ich SQLite benutzen.
Benutzeravatar
noisefloor
User
Beiträge: 3858
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

1200 Reads + Updates in 20 Sekunden ist IMHO für keine RDBMS ein Problem. Zumal SQLite ja in der Hinsicht so wie so nicht langsamer ist als MySQL & Co.

Bist du _sicher_ dass deine Performance-Bremse nicht woanders liegt?

Gruß, noisefloor
BlackJack

@Trubinial Guru: Ich weiss jetzt nicht so ganz was ich mit der Antwort anfangen soll. Das klingt so als wenn Du glaubst ich wollte von einer SQL-Datenbank abraten. Ich bin schon davon ausgegangen, dass die SQL-Datenbank eine feste Grösse ist. Nur das was Du erreichen willst, da sehe ich nicht wie man das in SQL ausdrücken kann. Beziehungsweise wenn es Wege gibt, werden die nicht schön aussehen, sondern nach Hacks.

Wo bleibt denn die Zeit? Wofür wird die verbraucht? Bist Du sicher das es überhaupt schneller geht? Gerade bei SQLite hat man ja nicht einmal besonders hohe Kommunikationskosten zwischen Programm und Datenbank, weil ja alles in einem Prozess läuft. Machst Du vielleicht irgend etwas ungünstiges, beispielsweise 1200 mal `commit()` statt nur einmal nach den Änderungen, oder die Abfrage aller Daten statt nur der Primärschlüssel, oder gibt es irgendwelche „eager”-Verknüpfungen bei SQLAlchemy wegen denen mehr abgefragt wird als eigentlich nötig wäre?

Auf der anderen Seite kann das Laufen im selben Prozess natürlich eventuell auch schlecht sein, weil eine Client/Server-Datenbank die Änderungen erst einmal im Speicher halten kann während der Client schon weiter arbeitet, und die Daten parallel dazu wegschreiben kann. Bei SQLite muss der „Client” in der Regel warten bis alle Änderungen geschrieben wurden. Das ist dann die Stelle an der man tiefer in die SQLite „Stellschrauben” eintauchen kann und entscheiden kann welche Garantien man von der Datenbank braucht und wie man commits und rollbacks umgesetzt haben möchte. Mögliches Stichwort „Write-Ahead Logging (WAL) vs. Rollback Journal”.
Antworten