SQLite und UPDATES mit spalte="spalte"

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
dede67
User
Beiträge: 8
Registriert: Sonntag 11. März 2012, 18:52

Moin!
ich hab da mal ein kleines Programm:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import sqlite3

connection=sqlite3.connect("/home/dede/tescht.sqlite")
cursor=connection.cursor()
cursor.execute('CREATE TABLE UIDPWD' +
               ' (ID        INTEGER NOT NULL PRIMARY KEY,' +
               '  dienst    VARCHAR(64),' +
               '  kommentar VARCHAR(255) )')
cursor.execute('CREATE UNIQUE INDEX dienst ON UIDPWD (dienst ASC)')
connection.commit()


d="foo"
k="bar"
cursor.execute('INSERT INTO UIDPWD (dienst, kommentar) VALUES ("'+d+'", "'+k+'")')
connection.commit()
cursor.execute('SELECT * FROM UIDPWD')
print cursor.fetchone()

d="fasel"
k="schwafel"
cursor.execute('UPDATE UIDPWD SET dienst="'+d+'", kommentar="'+k+'"')
connection.commit()
cursor.execute('SELECT * FROM UIDPWD')
print cursor.fetchone()


d="blub"
k="kommentar"
cursor.execute('UPDATE UIDPWD SET dienst="'+d+'", kommentar="'+k+'"')
connection.commit()
cursor.execute('SELECT * FROM UIDPWD')
print cursor.fetchone()

d="dienst"
k="<kommentar>"
cursor.execute('UPDATE UIDPWD SET dienst="'+d+'", kommentar="'+k+'"')
connection.commit()
cursor.execute('SELECT * FROM UIDPWD')
print cursor.fetchone()
Das liefert als Ergebnis:
(1, u'foo', u'bar')
(1, u'fasel', u'schwafel')
(1, u'blub', u'schwafel')
(1, u'blub', u'<kommentar>')

Man beachte die dritte und die vierte Zeile.
Laut Programm würde ich da erwarten:
(1, u'blub', u'kommentar')
(1, u'dienst', u'<kommentar>')

Es gibt also irgendwie ein Problem damit, einen UPDATE spalte="spalte" erfolgreich ins DBMS zu bekommen.
Mache ich einen Denkfehler?
Ist das ein Bug?
Oder hat das Sinn?
Gibts einen eleganten Workaround?


BTW: ein "rpm -qa|grep -i sqlite" liefert
  • libsqlite3-0-3.7.8-1.1.2.x86_64
    python-pysqlite-2.6.3-12.12.x86_64
    mono-data-sqlite-2.10.6-2.1.3.x86_64
    sqlite3-3.7.8-1.1.2.x86_64
    libqt4-sql-sqlite-4.7.4-19.6.1.x86_64
dede
BlackJack

@dede67: Man sollte wirklich keine SQL-Anweisungen mit Werten durch Zeichenkettenformatierung erstellen. Das bringt nur Probleme und Sicherheitslücken. Verwende Platzhalter und die `execute()`-Methode um die Werte in die Anfrage zu bekommen und schon klappt es.

Literale Zeichenketten die nur durch „whitespace” voneinander getrennt sind, werden vom Compiler zu einer Zeichenkette zusammengesetzt.

Code: Alles auswählen

import sqlite3


def main():
    connection = sqlite3.connect(':memory:')
    cursor = connection.cursor()
    cursor.execute(
        'CREATE TABLE UIDPWD'
        ' (ID        INTEGER NOT NULL PRIMARY KEY,'
        '  dienst    VARCHAR(64),'
        '  kommentar VARCHAR(255) )'
    )
    cursor.execute('CREATE UNIQUE INDEX dienst ON UIDPWD (dienst ASC)')
    connection.commit()

    cursor.execute(
        'INSERT INTO UIDPWD (dienst, kommentar) VALUES (?, ?)', ('foo', 'bar')
    )
    connection.commit()
    cursor.execute('SELECT * FROM UIDPWD')
    print cursor.fetchone()
    
    for service, comment in [
        ('fasel', 'schwafel'),
        ('blub', 'kommentar'),
        ('dienst', '<kommentar>'),
    ]:
        cursor.execute(
            'UPDATE UIDPWD SET dienst=?, kommentar=?', (service, comment)
        )
        connection.commit()
        cursor.execute('SELECT * FROM UIDPWD')
        print cursor.fetchone()


if __name__ == '__main__':
    main()
dede67
User
Beiträge: 8
Registriert: Sonntag 11. März 2012, 18:52

Code: Alles auswählen

[...]
        cursor.execute(
            'UPDATE UIDPWD SET dienst=?, kommentar=?', (service, comment)
        )
[...]
Klappt!
Perfekt!
Vielen Dank BlackJack - diese Art Antwort wünsche ich mir in Foren häufiger!
Da werde ich doch gleich meinen ganzen Queries umbauen, zumal es auch die Problematik mit " und ' löst.

dede
Antworten