Seite 1 von 1

SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 10:41
von nfehren
Hallo,
Ich bin wieder an einer kleinen Übungsaufgabe. Ich will eine Abfrage über die Shell machen, die Informationen zu einem "ToDo" sammelt.
Das soll dann in eine Datenbank übernommen werden. Soweit so gut, es klappt auch alles, das ToDo wird übernommen und gespeichert. Blos wenn ein neues ToDo dazu kommt wird das alte überschrieben.

Hier erstmal der Code:

Code: Alles auswählen

import time
import datetime
import sqlite3

def tableCreate():
    c.execute("CREATE TABLE ToDo("
              "Nr INT,"
              "Datum TEXT,"
              "Notiz TEXT,"
              "Menge REAL)")

def dataEntry():
    Datum = str(datetime.datetime.fromtimestamp(int(time.time())).strftime('%d.%m.%Y %H:%M'))
    c.execute('INSERT INTO ToDo(Nr,Datum,Notiz,Menge) VALUES (?,?,?,?)',
              (Nr, Datum, Notiz, Menge))
    conn.commit()

def readData():
    sql = "SELECT * FROM ToDo"
    for row in c.execute(sql):
        print(row)

conn = sqlite3.connect('tut.db')
c = conn.cursor()
c.execute("drop table if exists ToDo")
conn.commit()

tableCreate()

Nr = int(input("Welche Nummer soll der Eintrag haben? "))
Notiz = input("Welche Notiz soll der Eintrag haben? ")
Menge = float(input("Geben sie die Menge an "))

dataEntry()
readData()
Wo habe ich etwas vergessen oder falsch gemacht, dass jedes mal überschrieben wird?

Danke für die Antworten, sonstige Verbesserungsvorschläge sind auch sehr erwünscht.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 11:01
von Sirius3
@nfehren: was meinst Du macht Zeile 25?

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 11:37
von nfehren
Es überschreibt, aber wenn ich das nicht drin habe lässt sich das Skript nicht ausführen, weil die Tabelle schon existiert.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 11:47
von BlackJack
@nfehren: Dann darfst Du die Tabelle halt nur erstellen wenn sie noch nicht existiert. Oder Du behandelst die dadurch entstehende Ausnahme, und *nur die*, durch ignorieren.

Die Zeile überschreibt auch nichts. Die löscht die Tabelle.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 12:45
von /me
nfehren hat geschrieben:Es überschreibt, aber wenn ich das nicht drin habe lässt sich das Skript nicht ausführen, weil die Tabelle schon existiert.
Man erstellt eine Tabelle nur einmal und zwar nur einmal während der gesamten Existenz der Datenbank, nicht einmal pro Programmaufruf.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 13:15
von nfehren
/me hat geschrieben:
nfehren hat geschrieben:Es überschreibt, aber wenn ich das nicht drin habe lässt sich das Skript nicht ausführen, weil die Tabelle schon existiert.
Man erstellt eine Tabelle nur einmal und zwar nur einmal während der gesamten Existenz der Datenbank, nicht einmal pro Programmaufruf.

Code: Alles auswählen

def tableCreate():
    c.execute("CREATE TABLE IF NOT EXISTS ToDo("
              "Nr INT,"
              "Datum TEXT,"
              "Notiz TEXT,"
              "Menge REAL)")
So, ist das richtig? Funktionieren tuts.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 13:26
von BlackJack
@nfehren: Jup, das geht, wobei das ``IF (NOT) EXISTS`` soweit ich weiss kein Standard-SQL ist.

Ich würde aus der `Nr` einen Primärschlüssel machen und aus dem `Datum` den Typ `TIMESTAMP`. Oder `DATE`, dann müsste man dem SQLite-Modul leider extra sagen dass das in ein entsprechendes Python-Objekt umgewandelt wird und nicht als Zeichenkette geliefert werden. Einer der Gründe warum ich auch bei SQLite gerne SQLAlchemy verwende, da werden solche sinnvollen Konvertierungen automatisch erledigt.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 13:49
von nfehren
BlackJack hat geschrieben:@nfehren: Jup, das geht, wobei das ``IF (NOT) EXISTS`` soweit ich weiss kein Standard-SQL ist.

Ich würde aus der `Nr` einen Primärschlüssel machen und aus dem `Datum` den Typ `TIMESTAMP`. Oder `DATE`, dann müsste man dem SQLite-Modul leider extra sagen dass das in ein entsprechendes Python-Objekt umgewandelt wird und nicht als Zeichenkette geliefert werden. Einer der Gründe warum ich auch bei SQLite gerne SQLAlchemy verwende, da werden solche sinnvollen Konvertierungen automatisch erledigt.
Habe ich so übernommen, danke :)

Ich möchte jetzt auch noch eine Funktion erstellen, mit der ich einen Eintrag löschen kann.
Dafür soll erst abgefragt werden, welcher Eintrag (Nr) gelöscht werden soll.
Wie ich das aber umsetzen soll mit der Variable beim löschen, da bin ich mir nicht ganz sicher.

Soweit bin ich:

Code: Alles auswählen

def delData():
    auswahl = int(input("Welchen Eintrag wollen sie löschen? "))
    c.execute("DELETE FROM ToDo WHERE Nr = (auswahl) VALUES (?)",
              (auswahl))
Es kommt aber eine Error meldung. Also stimmt irgendwas mit der Syntax nicht..

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 13:55
von Hyperion
nfehren hat geschrieben: Ich möchte jetzt auch noch eine Funktion erstellen, mit der ich einen Eintrag löschen kann.
Dafür soll erst abgefragt werden, welcher Eintrag (Nr) gelöscht werden soll.
Wie ich das aber umsetzen soll mit der Variable beim löschen, da bin ich mir nicht ganz sicher.
Ich würde ja Nachfragen (also Benutzerinteraktion) und Funktionalität trennen! Erstelle einfach zwei Funktionen, eine für die Nachfrage und eine, die das Löschen durchführt und als Parameter die Nummer erhält.
nfehren hat geschrieben: Es kommt aber eine Error meldung. Also stimmt irgendwas mit der Syntax nicht..
Probiere das doch zunächst in einer SQL-Shell aus! Wenn Du dann die richtige Syntax hast, brauchst Du nur noch den Platzhalter einbauen.

(Ja, ich verrate Dir hier absichtlich nicht die Lösung, denn die ist wirklich trivial :-) )

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 14:30
von nfehren
Hyperion hat geschrieben: Probiere das doch zunächst in einer SQL-Shell aus! Wenn Du dann die richtige Syntax hast, brauchst Du nur noch den Platzhalter einbauen.

(Ja, ich verrate Dir hier absichtlich nicht die Lösung, denn die ist wirklich trivial :-) )
delete from Todo where nr = 1 , klappt. Aber das ist halt ohne Variable

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Donnerstag 4. September 2014, 14:39
von BlackJack
@nfehren: Das würde sich aber auch mit Variable von dem Unterscheiden was Du vorher mit dem Programm probiert hast.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Freitag 5. September 2014, 09:24
von nfehren

Code: Alles auswählen

def delData():
    auswahl = int(input("Welchen Eintrag wollen sie löschen? "))
    c.execute("DELETE FROM ToDo WHERE Nr IS '{0}'".format(auswahl))
    conn.commit()

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Freitag 5. September 2014, 10:25
von Sirius3
@nfehren: Nein. Du formatierst wieder was in SQL-Asudrücke rein. Nr ist eine Zahl, du vergleichst mit einem String, was Ausnahmsweise bei SQLite keine Rolle spielt, an sich aber falsch ist.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Freitag 5. September 2014, 10:41
von /me
Sirius3 hat geschrieben:@nfehren: Nein. Du formatierst wieder was in SQL-Asudrücke rein. Nr ist eine Zahl, du vergleichst mit einem String, was Ausnahmsweise bei SQLite keine Rolle spielt, an sich aber falsch ist.
Ergänzend dazu: Wenn man einen exakten Stringvergleich haben will nimmt man natürlich das Gleichheitszeichen und nicht LIKE.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Freitag 5. September 2014, 11:02
von BlackJack
@nfehren: Geht das tatsächlich mit ``IS``? Und Du formatierst da einen vom Benutzer eingegebenen Wert direkt in eine SQL-Anweisung. Das ist ein absolutes No-Go, weil eine riesige Sicherheitslücke und Fehlerquelle.

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Freitag 5. September 2014, 12:32
von Hyperion
BlackJack hat geschrieben:Und Du formatierst da einen vom Benutzer eingegebenen Wert direkt in eine SQL-Anweisung. Das ist ein absolutes No-Go, weil eine riesige Sicherheitslücke und Fehlerquelle.
Was besonders erstaunlich ist, da er den richtigen Mechanismus ja schon mal benutzt und gezeigt hat!

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Freitag 5. September 2014, 13:06
von pillmuncher
Aha. Ist wohl mal wieder Zeit hierfür: http://xkcd.com/327/

Re: SQLite3 Datenbank überschreibt db file

Verfasst: Freitag 5. September 2014, 13:12
von Hyperion
:twisted: Den kannte ich noch nicht - nice!