SQLITE3: Fehler: no such column

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

Moin, habe das Problem, das offensichtlich eine Spalte nicht gefunden wird.

Code: Alles auswählen

def create_scores_db():
    create_db = sqlite3.connect('scores.db')
    cursor = create_db.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS npass ( datum TEXT,
                                                        schreien TEXT,
                                                        verhalten TEXT,
                                                        vitalzeichen TEXT,
                                                        extremitaeten TEXT,
                                                        gesicht TEXT)''')
    create_db.commit()


def insert_scores_db():
    insert_db = sqlite3.connect('scores.db')
    insert_db.execute ('''INSERT INTO npass ( datum,
                                          schreien,
                                          verhalten,
                                          vitalzeichen,
                                          extremitaeten,
                                          gesicht) VALUES ({0}, {1}, {2}, {3}, {4} , {5})'''.format ( npass_datum_entry.get(),
                                                                                               npass_weinen_intVar.get(),
                                                                                               npass_verhalten_intVar.get(),
                                                                                               npass_vitalzeichen_intVar.get(),
                                                                                               npass_extremitaeten_intVar.get(),
                                                                                               npass_gesicht_intVar.get()))


    cursor = insert_db.cursor()
    print (npass_gesicht_intVar.get(), a)
    insert_db.commit()

Die Fehlermeldung bei insert_scores_db() lautet, wenn ich in das Feld npass_datum_entry eine zeichenkette (z.B. 01.01.2018) eingeben "....no such column: .2018: syntax error", wenn ich eine zahl eingebe, dann mekert python nicht und die zahl ist auch in der db sichtbar.
Was geht da vor sich?
BlackJack

@lernePython: Niemals Werte als Zeichenketten in SQL hineinformatieren! Das geht im besten Fall leicht kaputt und ist im schlechtesten Fall einfach nur gefährlich weil der Benutzer damit nahezu beliebiges SQL einschleusen kann. Von Datenbankabfragen bis zum löschen oder verändern von Daten.

Für die Werte schreibt man Platzhalter in das SQL und übergibt dann die Werte als zweites Argument an die `execute()`-Methode.

Warum deklarierst Du die Spalten alle TEXT wenn im Endeffekt keine einzige davon wirklich Text ist?
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

Also so?:

Code: Alles auswählen


i_datum = npass_datum_entry.get()
    i_weinen = npass_weinen_intVar.get()
    i_verhalten = npass_verhalten_intVar.get()
    i_vitalzeichen = npass_vitalzeichen_intVar.get()
    i_extremitaeten = npass_extremitaeten_intVar.get()
    i_gesicht = npass_gesicht_intVar.get()

[....]

sql = ("INSERT INTO npass VALUES(%s, %s,%s, %s,%s, %s)"  %(i_datum, i_weinen, i_verhalten, i_vitalzeichen, i_extremitaeten, i_gesicht))
cursor.execute (sql)
Wegen der Datentypen... hast Du natürlich recht. Es muss heißen DATE und INTEGER
BlackJack

@lernePython: Das ist doch genau das gleiche mit ``%`` statt mit `format()`. Die Werte werden als *zweites Argument* an `execute()` übergeben. Und die Platzhalter müssen zum Datenbankmodul passen. Das `sqlite3`-Modul verwendet den SQL-Standard (das Fragezeichen) für unbenannte Platzhalter.

Was sollen die ganzen `i_`-Präfixe bedeuten?
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

o.k. dann so?

Code: Alles auswählen

def insert_scores_db():
    werte = (npass_datum_entry.get(),npass_weinen_intVar.get(), npass_verhalten_intVar.get(),npass_vitalzeichen_intVar.get(), npass_extremitaeten_intVar.get(),npass_gesicht_intVar.get())
    insert_db = sqlite3.connect('scores.db')
    cursor = insert_db.cursor()
    sql = "INSERT INTO npass VALUES(?, ?,?, ?,?,?)"
    cursor.execute (sql, werte)
    insert_db.commit()

lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

So, wie gehe ich aber hier mit einem Platzhalter um:

Code: Alles auswählen

def loesche_eintrag():
    oeffnen_db = sqlite3.connect('scores.db')
    cursor = oeffnen_db.cursor()
    werte = int(loesche_id_entry.get())
    sql = "UPDATE npass SET deleted = 1 WHERE id = ?"
    cursor.execute(sql, werte)
    oeffnen_db.commit()
hier bekomme ich immer die Fehlermeldung:
ValueError: parameters are of unsupported type
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

du musst immer ein Tupel oder eine Liste übergeben, auch wenn die nur ein Element hat.

Außerdem würde es wahrscheinlich helfen, wenn du mal die Doku zum sqlite3 Modul lesen würdest. Da ist das alles erklärt und du müsstest weniger Rum raten.

Gruß, noisefloor
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

Danke für die Antwort. Natürlich habe ich mir schon einiges angelesen, bin aber bei meinem Problem auf folgenden Code gestoßen, bei dem auch kein Tupel bzw. keine Liste sondern eine int übergeben wird. Daher bin ich jetzt ein bisschen irritiert.

Code: Alles auswählen


import sqlite3 as lite
import sys

uId = 1
uPrice = 62300 

con = lite.connect('test.db')

with con:

    cur = con.cursor()    

    cur.execute("UPDATE Cars SET Price=? WHERE Id=?", (uPrice, uId))        
    con.commit()
    
    print "Number of rows updated: %d" % cur.rowcount

Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@lernePython: in Deinem Beispiel werd ja auch ein Tuple mit 2 Ints an execute übergeben.
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

:oops:
o.k. vielen Dank.
Aber dennoch: wenn ich die Werte in einem Tupel übergebe bekomme ich einen Fehler. Die Übergabe in einer Liste ist dann korrekt und ohne Fehlermeldung.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@lernePython: das kann nicht sein. Was hast Du genau versucht?
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

Code: Alles auswählen

 werte = int(loesche_id_entry.get())
    liste_loeschen.append(werte)   
    cursor.execute("UPDATE npass SET deleted = 1 WHERE id =?", (werte))

mit der Fehlermeldung: cursor.execute("UPDATE npass SET deleted = 1 WHERE id =?", (werte))
ValueError: parameters are of unsupported type

Wenn ich statt dessen

Code: Alles auswählen

 werte = int(loesche_id_entry.get())
    liste_loeschen.append(werte)
    cursor.execute("UPDATE npass SET deleted = 1 WHERE id =?", [werte])
verwende, ist alles in Ordnung, der Befehl wird ausgeführt.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

das sind Python-Basics:

Code: Alles auswählen

('wert')
sieht aus wie ein Tupel, ist aber keins. Dafür muss noch ein Komma dahinter:

Code: Alles auswählen

>>> a = ('wert')
>>> type(a)
<type 'str'>
>>> b = ('wert', )
>>> type(b)
<type 'tuple'>
>>>
Gruß, noisefloor
Zuletzt geändert von noisefloor am Sonntag 5. Februar 2017, 20:09, insgesamt 1-mal geändert.
lernePython
User
Beiträge: 18
Registriert: Freitag 3. Februar 2017, 20:01

doppelt :oops: :oops:
... und vielen Dank für Eure Geduld
Antworten