2016-03-26 5 views
0

Für jede Schleife in dem folgenden Code, fügt die INSERT INTO den zugewiesenen Wert auf die richtige Spalte aber in einer neuen Zeile:Insert Werte in SQLite einer Zeile zu einem Zeitpunkt

import sqlite3 

conn = sqlite3.connect('testtable.sqlite3') 
cur = conn.cursor() 
cur.executescript(''' DROP TABLE IF EXISTS Tracks; 
         CREATE TABLE Tracks (id, singer, song)''') 

lst = ['id', 'singer', 'song'] 

for i in range(len(lst)): 
    print 'Enter a value for column', lst[i] 
    insdata = raw_input('>>> ') 
    cur.execute('''INSERT INTO Tracks ({col}) VALUES (?)'''\ 
    .format(col=lst[i]), (insdata,)) 
conn.commit() 
conn.close() 

Frage: Wie kann Ich sage SQLite nicht zu Zeile in jeder Schleife ändern und füllen Sie die Tabelle eine Zeile auf einmal?

Hinweis: Ich möchte nicht explizit auf alle Spaltennamen in meinem Code verweisen (wie INSERT INTO-Tabelle (alle Spalten)), weil ich in meinem Übungsskript ihren Namen und ihre Gesamtzahl eingeben muss .

+2

Sie können nicht "einen Teil einer Zeile" in ein RDBMS einfügen; Sie müssen die entsprechenden Parameterlisten und Abfrageparameter generieren. Achten Sie auch auf SQL-Injection in den Spaltennamen, und wenn Sie nicht an einem Schema-unabhängig arbeiten, ist ein dynamisch geändertes Schema normalerweise die falsche Lösung. –

+0

Ich übe nur für mich selbst, versuche einige Mitarbeiter, neue Konzepte anzuwenden. Ich bekomme den ersten Teil Ihrer Antwort nicht wirklich. Trotzdem danke! – ToucHDowN

Antwort

1

Ändern Sie nicht die Datenbank innerhalb der Schleife. Verwenden Sie stattdessen die Schleife, um eine Datenstruktur (Liste, Wörterbuch ...) mit allem zu füllen, was Sie in der neuen Zeile verwenden möchten. Verwenden Sie nach der Schleife diese Datenstruktur, um die INSERT...-Klausel mit allen Daten zu erstellen.

Falls es nicht klar ist: Sie können SQLite nicht zu INSERT ... anweisen, ohne eine neue Zeile zu erstellen. INSERT erstellt immer eine neue Zeile.

+0

Vielen Dank für Ihre Antwort, wahrscheinlich musste ich klarer sein. Ich habe unten eine funktionierende Lösung gefunden. – ToucHDowN

1

Hoffentlich war es machbar. Ich antworte auf mich selbst für zukünftige Referenz und den obigen Code zum Vergleich. Ich kommentiere, was ich getan habe und wie ich im Code eine Antwort auf mein Problem gefunden habe. obwohl Gefühl traurig für ein Problem zu beschreiben Downvoted worden, die tatsächlich gelöst werden konnten den folgenden Trick mit ...

import sqlite3 

conn = sqlite3.connect('testdb.sqlite3') 
cur = conn.cursor() 

lst = ['id', 'singer', 'song'] # let's assume that through prompts, user has 
           # previously added these values and the 
           # script put them in this list. 

cur.executescript('''DROP TABLE IF EXISTS Tracks; 
        CREATE TABLE Tracks (id, singer, song)''') 
conn.commit() 

def populate_tb(): 
    print 'Insert value for column: ', lst[0] 
    inp = raw_input('>>> ') # user types the value for the first column (in 
          # this example, id column) 
    cur.execute('INSERT INTO Tracks ({col}) VALUES (?)'\ 
.format(col=lst[0]), (inp,)) 
         # the value is inserted to id column. 
    conn.commit() 
    if len(lst)-1 > 1: # meaning, continue iff user created a table with 
         # more than one column. I subtract one because lst[0] 
         # item has already been assigned a value above with 
         # the INSERT. 
     for i in range(len(lst)-1): # I run a loop for the remaining list 
            # items (singer, song columns) 
      print 'Insert value for column: ', lst[i+1] 
      inps = raw_input('>>> ') 
      cur.execute('UPDATE Tracks SET {col} = (?) WHERE id = (?)'\ 
.format(col=lst[i+1]), (inps,inp)) 
      # And here is the solution. I just UPDATE the newly created row so 
      # I get what I want: user is prompted to populate a table, 'cell 
      # by cell', horizontally, without changing line as it was 
      # happening with my initial code in the top. Instead of 
      # declaring explicitly which columns to populate (which is 
      # impossible in my scenario since the user is prompted 
      # dynamically to create the columns), I use only one column 
      # reference which varies according to the loop counter that 
      # traverses list's items. 
      conn.commit() 

populate_tb() 

Also meine ersten Frage (angesichts unserem Kontext): Wie kann ich SQLite sage nicht zu die Zeile in jeder Schleife ändern und die Tabelle Zeile für Zeile auffüllen? ist beantwortet: Sie können SQLite sagen, dass Sie nur den ersten Wert einfügen und dann aktualisieren Sie den Rest der leeren Zellen in dieser Zeile.

+0

Mit diesem Ansatz, wenn das Programm aus irgendeinem Grund in der Mitte abstürzt Sie am Ende mit einer halb-bevölkerten Zeile mit einigen (oder viele) leere Felder, die möglicherweise oder wollen nicht was Sie wollen. Wenn Sie nur einen INSERT verwenden, handelt es sich um eine atomare Operation. Sie haben entweder die Zeile mit allen angegebenen Feldern oder gar nichts eingefügt. Normalerweise bevorzugen die Leute das Letztere, deshalb wird so viel Aufwand betrieben, um SQL-Operationen atomar zu machen und Dinge wie Transaktionen existieren. – Goyo

Verwandte Themen