2016-10-30 5 views
0

Ich habe eine SQLite-Tabelle mit einer konstanten Anzahl von Zeilen. Aber während ich Werte erzeuge, die von einigen dieser Spalten abgeleitet sind (neue Features), möchte ich neben vorhandenen Spalten Spalten hinzufügen, ohne neue Zeilen zu erstellen. Ich kann eine Spalte mit ALTER TABLE hinzufügen, aber Aufruf cur.executemany("INSERT INTO...") bewirkt, dass die Werte in neuen Zeilen angehängt werden.Aktualisieren mehrerer Werte in einer SQLite-Spalte mit Python

Ich habe versucht:

cur.executemany("UPDATE DOS_APPENDIX SET FEATURE2=?", [(val,) for val in ["a", "b", "c"]])

Aus irgendeinem Grund dies die "c" führt über die Reihen 1, 2, 3 in der Spalte FEATURE2 dupliziert werden. Und es ist langsam auf einer großen Liste (~ 2 Millionen).

Gibt es eine Möglichkeit zum Massenupdate? Etwas so anmutig und schnell wie das Anrufen cur.executemany(INSERT INTO...)?

Muss ich die Zeilen einzeln mit einer for Schleife aktualisieren?

Wenn ja, wie würde ich dies tun, wenn ich keine WHERE Bedingung (nur Zeilennummern) habe?

Hinweis: Die Erstellung einer parallelen Spalte neben einer vorhandenen Spalte erfolgt mit Nullwerten. Diese werden dann überschrieben.

Antwort

2
  1. Wenn Sie UPDATE tbl SET column='value' verwenden - Sie erhalten die value in allen Zeilen in diesem column. Dies ist genau das, was diese Abfrage tut. Wenn Sie den Wert nur auf bestimmte Zeilen (oder auf bestimmte Spalte) festlegen mögen, sollten Sie die Abfrage entsprechend ändern (mit where column1='some value' oder durch die Spaltennamen zu ändern
  2. Wenn Sie eine Tabelle mit ~ 2M Zeilen aktualisieren -. Abhängig von der Menge Zeit der Daten dauert es :) Wenn Sie take a look here (die sehr alt ist, und wahrscheinlich sind die Dinge jetzt viel schneller), können Sie das Update von 25K Zeilen in sQLite sehen sie 2,4 Sekunden dauerte (jetzt sie mit 80 Doppelzimmer). Große Updates brauchen Zeit.
  3. Sie können Bulk-Update verwenden, aber ich bin mir nicht sicher, was genau Sie versuchen zu tun. Wenn Sie column2 einstellen möchten value2 wo column1 = value1 können Sie:


cur.executemany("UPDATE DOS_APPENDIX SET column2=? WHERE column1=?", [(column2_val, column1_val) for ...]) 

In der Regel - wenn Sie sagen: „Ich habe keinen WHERE Zustand haben (nur Zahlen Zeile) "- Das ist sehr problematisch. Sie können limit verwenden, wenn Sie genau wissen, welche Zeilen Sie, aber die Reihenfolge der Zeilen aktualisieren möchten, können ändern, so wirklich dagegen ich empfehlen. Es wird viel besser sein, ein id zu Ihren Zeilen hinzuzufügen und es mit Ihrer UPDATE Abfrage zu verwenden.

+0

Ich erwarte, dass 'UPDATE' länger dauert, weil es die Nullwerte überschreibt. Aber ich hatte gehofft, es würde nicht viel länger dauern als 'INSERT' (was schnell ist, sogar mit 2 Millionen Datensätzen). Vielleicht ist dies eine unkonventionelle Verwendung einer Datenbank (um ihre Struktur zu ändern), aber ich möchte die Werte neuer Funktionen speichern, während ich sie berechne. Ich werde versuchen, eine 'id' hinzuzufügen und vergleichen Sie diese relativ zu löschen und neu erstellen die Tabelle mit neuen Spalten. Vielen Dank. – zadrozny

+0

Wenn Sie sagen, dass Sie nicht erwarten würden, dass es viel länger dauert - haben Sie versucht, die 2M Zeilen einzufügen? Wie viel Zeit hat es gedauert? – Dekel

+0

Ja. Paar Sekunden höchstens. UPDATE wurde nach über einer Minute noch nicht ausgeführt und hat meinen Prozessor belastet, also habe ich ihn getötet. – zadrozny

3

In einer relationalen Datenbank, werden Sie wahrscheinlich nicht wollen, zu tun, was Sie beschreiben, wie es normalization bricht.

Was ich vorschlagen, dass Sie eine Feature-Tabelle, wo Sie die Eigenschaften speichern für jede Zeile:

CREATE TABLE observations (id INTEGER); 
CREATE TABLE features (id INTEGER, name TEXT); 
CREATE TABLE values (row_id INTEGER, feature_id INTEGER, value FLOAT); 

Auf diese Weise können neue Funktionen durch Hinzufügen einer Zeile zur features Tabelle und alle entsprechenden Zeilen hinzufügen zu der values Tabelle.

+0

Ich habe dich auf deinen Vorschlag aufgenommen. Dies bedeutet jedoch, dass jedes Feature 2 Millionen Zeilen zur Wertetabelle hinzufügt. Ich verwende SQLite für jetzt. Ich weiß, dass es viel kann, aber ist das wirklich die beste/einzige Möglichkeit, dies in einem RDB zu tun? Oder sollte ich sollte ich einen anderen Datenspeicher verwenden? – zadrozny

+0

So funktionieren diese Arten von Datenbanken. Sie sind normalerweise für Reihenergänzungen optimiert. Hdf kann schneller sein, und wenn Sie nur nach einer Möglichkeit suchen, große Arrays zu speichern, sollten Sie in Pytables schauen. Aber Hdf hat Probleme mit der Atomarität. – chthonicdaemon

Verwandte Themen