Datensatz bearbeiten

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Hallo zusammen,

wie kann man im nachinhein, Daten in einem Datensatz ergänzen oder verändern? Ich komme hier leider gerade nicht weiter.

Vielen Dank im voraus
Benutzeravatar
Käptn Haddock
User
Beiträge: 169
Registriert: Freitag 24. März 2006, 14:27

Wie sieht denn dein Datensatz aus? Liste, Dictionary, Klasse, Datenbankabfrage? Die Glaskugel ist leider etwas trüb gerade.

Gruß Uwe
---------------------------------
have a lot of fun!
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

sqlite3 datenbank wenn du das meinst. Hatte es irgendwie vergessen rein zu schreiben :)
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Deine Beschreibung ist vollkommen ungenügend. Sie entspricht etwa:

"Wie kann ich an meinem Auto etwas ändern?"
"Was willst du denn ändern?"
"Einen Audi."

Vielleicht fällt dir selber auf, dass da ein wenig Information fehlt. Was *genau* willst du ändern? Wie sieht die Tabelle aus? Wo kommt die Tabelle her? Willst du etwas löschen/hinzufügen/anpassen? Wenn du nicht den entsprechenden Code zeigst, dann wird das hier nichts.
Das Leben ist wie ein Tennisball.
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Nagut ihr habt es so gewollt :P

Code: Alles auswählen

from tkinter import *
import sqlite3
import time
import datetime

con = sqlite3.connect('pastedata.db')
cursor = con.cursor()

fenster = Tk()
title = fenster.title('Lötpastenkontrolle Version 0.2')

def springen1(event):
    name.focus_set()

def springen2(event):
    datum_ablaufh.focus_set()

def springen3(event):
    abschicken.focus_set()

def springen4(event):
    seriennummer.focus_set()

def senden():
    datum_k = datetime.datetime.now()
    datum_3 = datetime.datetime.now() + datetime.timedelta(days=3)
    datum_ab = datetime.datetime.now() + datetime.timedelta(hours=4)
    werte = (seriennummer.get(),
             name.get(),
             datum_k,
             datum_ablaufh.get(),
             datum_ab,
             datum_3,
             "",
             "")
    sql = "INSERT INTO paste VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
    cursor.execute(sql, werte)
    con.commit()
    seriennummer.delete('0',END)
    name.delete('0',END)
    datum_ablaufh.delete('0',END)
    seriennummer.focus_set()

#def ausgabe():
#    test = cursor.execute("""SELECT * FROM paste WHERE seriennummer=2""")
#    test1 = test.fetchall()
#    ausgabe1.config(text=test1)


seriennummer = Entry(fenster, font=('Arial', 30))
name = Entry(fenster, font=('Arial', 30))
datum_ablaufh = Entry(fenster, font=('Arial', 30))

Label(fenster, text="Seriennummer:").grid(column=0, row=0)
seriennummer.bind("<Return>", springen1)
seriennummer.focus_set()
seriennummer.grid(column=1, row=0)

Label(fenster, text="Name:").grid(column=0, row=1)
name.bind("<Return>", springen2)
name.grid(column=1, row=1)

Label(fenster, text="MHD Hersteller:").grid(column=0, row=2)
datum_ablaufh.bind("<Return>", springen3)
datum_ablaufh.grid(column=1, row=2)

abschicken = Button(master=fenster,
                    text="Bestätigen",
                    command=senden,
                    font=("Arial", 30))
abschicken.bind("<Return>", springen4)
abschicken.grid(column=1, row=3)

#ausgabe1 = Label(master=fenster,
#                font=("Arial", 10),
#                text="Bitte Scannen")
#
#ausgabe1.grid(row=4)


fenster.mainloop()
Kurze erklärung was ich machen will. Ausgangssituation ist eine Dose mit inhalt. Diese Dose hat eine feste und einmalige Seriennummer.Es gibt ein festes MHD auf der Dose. Wird die Dose aus dem Kühlschrank geholt muss der Inhalt in 3 Tagen verbraucht sein. Der Inhalt darf erst 4 Stunden nachdem er aus dem Kühlschrank geholt wurde genutzt werden. Wurde die dose dann nach den 4 Stunden geöffnet ist der Inhalt nur noch 8 Stunden haltbar.

datum_k = wann aus Kühlschrank, datum_h MHD hersteller, datum_ab Zeit wann die 4 stunden rum sind, datum_3 MHD nachdem er aus dem kühlschrank genommen wurde (3tage), datum_o die zeit wann geöffnet, datum_ende zeit nach den 8 stunden.

Nachdem die dose aus dem kühlschrank geholt wurde werden die 3 schon vorhandenen felder ausgefüllt. Nach dem mindestens 4 Stunden rum sind soll sie dann nochmal gescannt werden (entry feld kommt noch) und somit die letzten beiden Felder in der datenbank füllen.

Code: Alles auswählen

import sqlite3
import time

# Datenbank
con = sqlite3.connect('pastedata.db')
cursor = con.cursor()

print("Verbindung hergestellt...")


# Tabelle erstellen
cursor.execute("""CREATE TABLE IF NOT EXISTS paste (
        seriennummer TEXT PRIMARY KEY,
        name TEXT,
        datum_k DATETIME,
        datum_h DATE,
        datum_ab DATETIME,
        datum_3 DATETIME,
        datum_o DATETIME,
        datum_ende DATETIME)"""
               )


print("Tabelle erstellt...")
con.close()
print("Verbindung geschlossen!")
Achja bin noch harter Anfänger was man warscheinlich an dem sehr unsauberen Code erkennen wird.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du suchst den "UPDATE"-Befehl von SQL ;-)

Für Tipps zum Code habe ich grad keine Zeit...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
bfm
User
Beiträge: 88
Registriert: Donnerstag 14. März 2013, 09:42

Hallo,

also die Funktionen springen1, springen2.........
kannst evtl. mit "event.widget.tk_focusNext().focus_set()" in eine allgemein nutzbare Funktion zusammenfassen. Den nächsten Focus erhält dann immer das Widget, das als nächstes den Focus erhält (das ist ja auch ein Deutsch LOL). Die Reihenfolge ist dann allerdings von tkinter bestimmt!

Ein einfaches Update sieht so aus (ein Beispiel aus einem Tutorial kopiert)
"UPDATE Books SET Author='Olaf Adlerson' WHERE Id=1"

==> setze bei allen Datensätzen mit der Id 1 in der Tabelle Books die Spalte Author mit 'Olaf Adlerson'
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Danke für die Lösung zu meinem Problem. Wobei ich nun ein weiteres Problem habe. Ich habe diese Funktion eingefügt.

Code: Alles auswählen

def senden1():
    datum_o = datetime.datetime.now()
    datum_ende = datetime.datetime.now() + datetime.timedelta(hours=8)
    sn = seriennummer.get()
    datum_abb = "SELECT datum_ab FROM paste WHERE seriennummer=?"
    ergebnis = cursor.execute(datum_abb, sn)
    ergebnis1 = ergebnis.fetchall()
    werte1 = (datum_o, sn)
    werte2 = (datum_ende, sn)
    ok = "UPDATE paste SET datum_o=? WHERE seriennummer=?"
    ok2 = "UPDATE paste SET datum_ende=? WHERE seriennummer=?"
    
    if datum_o <= ergebnis1:
        cursor.execute(ok, werte1)
        cursor.execute(ok2, werte2)
und wenn ich den Button Drücke der diese funktion aufruft kommt diese Fehlermeldung:

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
return self.func(*args)
File "/home/christoph/Vorlagen/paste1.py", line 59, in senden1
if datum_o <= ergebnis1:
TypeError: unorderable types: datetime.datetime() <= list()

Ich denke auch zu verstehen was das bedeutet. Im klartext vergleiche ich Äpfel mit Birnen (korrigiert mich wenn ich falsch liege) aber wie kann ich es machen das er mit den Daten(Datum) in der SQL Tabelle rechnet?
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Du hast es doch schon erkannt. Du versuchst hier ein datetime-Objekt mit einer Liste zu vergleichen. Das geht natürlich nicht. Statt der Liste benötigst du auch ein datetime-Objekt. Das wiederum kannst du dir bestimmt aus einem Eintrag der Liste holen.
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Hmm hat noch nicht ganz geklappt. versuche es heute abend nochmal die Lösung zu finden wenn ich von der Arbeit komme aber danke schonmal.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Vielleicht das mal als Tipp:

Code: Alles auswählen

wert = 42
werte = [1, 2, 3, 42]
wert <= werte
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-c96b6c9681ea> in <module>()
----> 1 wert <= werte

TypeError: unorderable types: int() <= list()

werte = [42]
wert <= werte
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-c96b6c9681ea> in <module>()
----> 1 wert <= werte

TypeError: unorderable types: int() <= list()

wert <= werte[0]
> True
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.2/tkinter/__init__.py", line 1402, in __call__
return self.func(*args)
File "/home/christoph/Vorlagen/paste1.py", line 59, in senden1
if datum_o <= ergebnis1[0]:
TypeError: unorderable types: datetime.datetime() <= str()

Langsam glaube ich das eventuell (warum auch immer) in derTabelle der eintrag nicht richtig als DATETIME deklariert wurde. Er erkennt ja jetzt das es keine Liste mehr ist aber ein string sollte es auch nicht sein.

cursor.execute("""CREATE TABLE IF NOT EXISTS paste (
seriennummer TEXT PRIMARY KEY,
name TEXT,
datum_k DATETIME,
datum_h DATE,
datum_ab DATETIME,
datum_3 DATETIME,
datum_o DATETIME,
datum_ende DATETIME)"""
)

so hab ich die Tabelle ja erstellt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du musst die Typen beim Auslesen auch entsprechend in Python Datentypen konvertieren! Das geht nicht automatisch...
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

hmm bekomme ich irgendwie nicht hin. In int() str() usw. ist es ja kein problem aber mit dem datum klappt es bei mir mal garnicht. Vielleicht hab ich gurken auf den Augen und gucke lieber morgen nochmal wenn ich ausgeschlafen bin.
BlackJack

@Hyperion: Doch das sollte eigentlich automatisch gehen. Wenn die Datenbankspalte als DATETIME deklariert ist und da auch tatsächlich ein entsprechender Wert eingetragen wurde, dann sollte bei der Abfrage kein `str`-Objekt geliefert werden.

Da sqlite3 beim Eintragen keinen Typ erzwingt vermute ich mal eher der Fehler wurde schon vorher gemacht und es wurden keine Datumsobjekte sondern Zeichenketten eingetragen — die jetzt natürlich auch bei der Abfrage zurückgeliefert werden.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

BlackJack hat geschrieben:@Hyperion: Doch das sollte eigentlich automatisch gehen. Wenn die Datenbankspalte als DATETIME deklariert ist und da auch tatsächlich ein entsprechender Wert eingetragen wurde, dann sollte bei der Abfrage kein `str`-Objekt geliefert werden.
Ah ok... hab wohl zu lange nichts mehr mit der DB-API 2 gemacht :oops:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

Ich poste nochmal den aktuellen code

Code: Alles auswählen

from tkinter import *
import sqlite3
import time
import datetime

# sql
con = sqlite3.connect('pastedata.db')
cursor = con.cursor()
#TK
fenster = Tk()
title = fenster.title('Lötpastenkontrolle Version 0.2')

#von entry zu entry springen
def springen1(event):
    name.focus_set()

def springen2(event):
    datum_ablaufh.focus_set()

def springen3(event):
    abschicken.focus_set()

def springen4(event):
    seriennummer.focus_set()

#absenden der daten bei neuer paste
def senden():
    datum_k = datetime.datetime.now()
    datum_3 = datetime.datetime.now() + datetime.timedelta(days=3)
    datum_ab = datetime.datetime.now() + datetime.timedelta(hours=4)
    werte = (seriennummer.get(),
             name.get(),
             datum_k,
             datum_ablaufh.get(),
             datum_ab,
             datum_3,
             "",
             "")
    sql = "INSERT INTO paste VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
    cursor.execute(sql, werte)
    con.commit()
    seriennummer.delete('0',END)
    name.delete('0',END)
    datum_ablaufh.delete('0',END)
    seriennummer.focus_set()

def senden1():
    datum_o = datetime.datetime.now()
    datum_ende = datetime.datetime.now() + datetime.timedelta(hours=8)
    sn = seriennummer.get()
    datum_abb = "SELECT datum_ab FROM paste WHERE seriennummer=?"
    ergebnis = cursor.execute(datum_abb, sn)
    ergebnis1 = ergebnis.fetchone()
    werte1 = (datum_o, sn)
    werte2 = (datum_ende, sn)
    ok = "UPDATE paste SET datum_o=? WHERE seriennummer=?"
    ok2 = "UPDATE paste SET datum_ende=? WHERE seriennummer=?"
    a = ergebnis1[0]

    
    if datum_o <= a:
        cursor.execute(ok, werte1)
        cursor.execute(ok2, werte2)

#def ausgabe():
#    test = cursor.execute("""SELECT * FROM paste WHERE seriennummer=2""")
#    test1 = test.fetchall()
#    ausgabe1.config(text=test1)


seriennummer = Entry(fenster, font=('Arial', 30))
name = Entry(fenster, font=('Arial', 30))
datum_ablaufh = Entry(fenster, font=('Arial', 30))
#
Label(fenster, text="Seriennummer:").grid(column=0, row=0)
seriennummer.bind("<Return>", springen1)
seriennummer.focus_set()
seriennummer.grid(column=1, row=0)

Label(fenster, text="Name:").grid(column=0, row=1)
name.bind("<Return>", springen2)
name.grid(column=1, row=1)

Label(fenster, text="MHD Hersteller:").grid(column=0, row=2)
datum_ablaufh.bind("<Return>", springen3)
datum_ablaufh.grid(column=1, row=2)

abschicken = Button(master=fenster,
                    text="Neue Paste",
                    command=senden,
                    font=("Arial", 25))
abschicken.bind("<Return>", springen4)
abschicken.grid(column=1, row=3, sticky=W)

abschicken1 = Button(master=fenster,
                     text="Paste Öffnen",
                     command=senden1,
                     font=("Arial", 25))
abschicken1.grid(column=1, row=3, sticky=E)
#
#ausgabe1 = Label(master=fenster,
#                font=("Arial", 10),
#                text="Bitte Scannen")

#ausgabe1.grid(row=4)


fenster.mainloop()

Code: Alles auswählen

import sqlite3
import time

# Datenbank
con = sqlite3.connect('pastedata.db')
cursor = con.cursor()

print("Verbindung hergestellt...")


# Tabelle erstellen
#cursor.execute("""CREATE TABLE IF NOT EXISTS paste (
#        seriennummer TEXT PRIMARY KEY, datum_entnahme DATETIME, datum_ablaufh DATE, datum_3tage DATETIME, name TEXT, datum_oeffnung DATETIME, datum_ablauf DATETIME)""")
cursor.execute("""CREATE TABLE IF NOT EXISTS paste (
        seriennummer TEXT PRIMARY KEY,
        name TEXT,
        datum_k DATETIME,
        datum_h DATE,
        datum_ab DATETIME,
        datum_3 DATETIME,
        datum_o DATETIME,
        datum_ende DATETIME)"""
               )


print("Tabelle erstellt...")
con.close()
print("Verbindung geschlossen!")
BlackJack

@Hyperion: Wie peinlich, ich habe auch schon lange nichts mehr damit gemacht. Ich verwende immer SQLAlchemy. Man muss bei der Verbindung das Argument ``detect_types=True`` mitgeben, damit das funktioniert. :oops:
Eisi
User
Beiträge: 62
Registriert: Sonntag 24. November 2013, 21:59

geht leider auch nicht

Code: Alles auswählen

con = sqlite3.connect('pastedata.db',
                      detect_types=True)
BlackJack

@Eisi: Bei mir geht das wenn die Spalte von Typ TIMESTAMP ist:

Code: Alles auswählen

In [24]: con = sqlite3.connect('test.db3', detect_types=True)

In [25]: cur = con.cursor()

In [26]: cur.execute('SELECT * FROM test')
Out[26]: <sqlite3.Cursor at 0xa4c1a60>

In [27]: cur.fetchall()
Out[27]: [(1, datetime.datetime(2014, 3, 14, 19, 59, 23, 672698))]
Ich fühle mich darin bestätigt SQLAlchemy zu verwenden. :-)
Antworten