Daten Eintragen in die Mysql Datenbank Scheitert.

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Guten Tag zusammen ,

ich habe ein Problem , ich Programmiere seit 1 Monat mit Python und komme soweit ein wenig damit klar.
Jetzt habe ich ein kleines Kontaktbuch gebaut wo ich Daten in die Datenbank einfügen möchte.
Ich habe laut Buch es so gemacht aber es geht nicht .

Vielleicht kann mir einer Helfen und mir sagen wie ich es richtig machen kann .

Ich habe ein Script mitgesendet , das Passwort habe ich mit Sternchen Extra gemacht.

Ich habe wie Ihr sehen könnt in den Input den Namen Manuel eingegeben um zu sehen ob es funzt .
Aber passiert nix . Ich wollte nämlich Später die name_temp.get() dadurch ersetzen .

Danke für Unterstützung im Voraus !

Code: Alles auswählen

def click_send():
    my_db = mysql.connector.connect(user='root', password='******', host='127.0.0.1', port=3306, database='login',
                                   auth_plugin='mysql_native_password')



    my_cursor = my_db.cursor()
    vorname = input('Arian')
    name = input('kauschick')
    ort = input('duisburg Rahm')

    val = f'"{vorname}", "{name}", "{ort}"'
    sql = f'INSERT INTO nachrichten VALUE ({val}'

    my_cursor.execute(sql)
    my_db.commit()



def hinzu_window():

    vorname_temp = StringVar()
    name_temp = StringVar()
    wohnort_temp = StringVar()


    extra_window = tk.Toplevel()
    extra_window.title("Schüler Liste (Hinzufügen")
    extra_window.geometry("900x650")

    user_info = tk.Label(extra_window,text="Shool List Update")
    user_info.grid(row=0,column=0,pady=40)
    user_info.configure(width="100")
    vorname_label = tk.Label(extra_window,text="Vorname des Schülers")
    vorname_label.grid()
    vorname_entry = tk.Entry(extra_window,width="40", textvariable=vorname_temp)
    vorname_entry.grid()
    name_label = tk.Label(extra_window, text="Name des Schülers")
    name_label.grid()
    name_entry = tk.Entry(extra_window, width="40", textvariable=name_temp)
    name_entry.grid()
    Wohnort_label = tk.Label(extra_window, text="Wohnort des Schülers")
    Wohnort_label.grid()
    wohnort_entry = tk.Entry(extra_window, width="40", textvariable=wohnort_temp)
    wohnort_entry.grid()
    label_btn = tk.Button(extra_window,text="Hinzufügen",command=click_send)
    label_btn.grid(pady=40)


Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@TorstenVoelker: Das nix passiert stimmt so nicht, MySQL beziehungsweise der Connector wird eine Ausnahme auslösen weil das SQL welches Du da als Zeichenkette zusammenbastelst, kein gültiges SQL ist.

Selbst wenn es das wäre: man bastelt nicht selbst Werte in SQL als Zeichenketten. Im besten Fall ist es ineffizient, es ist durch Nutzereingaben leicht ”kaputt” zu machen, und im schlechtesten Fall ist es eine Sicherheitslücke. Stichwort SQL-Injection. Die `execute()`-Methode nimmt zwei Argumente: Die SQL-Anweisung mit Platzhaltern für die Werte, und eine Sequenz mit den Werten.

`my_` ist ein unnsinniger Namenszusatz wenn es nicht auch `our_` oder `their_` oder etwas vergleichbares für den Namen gibt.

Sowohl die Datenbankverbindung als auch den Cursor sollte man sauber schliessen wenn man damit fertig ist. Die ``with``-Anweisung und `contextlib.closing()` bieten sich da an.

Die eigentliche Eingabe als Prompt für `input()` sieht komisch aus.

Bei dem INSERT sollte man explizit die Spaltennamen angeben, sonst wird das ”lustig” wenn man die Spalten mal ändert in der Anzahl oder der Reihenfolge. Zudem kann das so nur funktionieren wenn es keinen Primärschlüssel in der Tabelle gibt, oder? Die Schüler müssen so nicht eindeutig sein, denn es kann Problemlos mehr als einen Peter Meier im gleichen Ort geben.

Auch wenn MySQL hier VALUE erlaubt, wäre es sinnvoller VALUES zu verwenden. Ich vermute das VALUE nicht mal Standard-SQL ist, sondern nur bei MySQL möglich ist.

Tabellenamen sind üblicherweise in der Einzahl benannt. Im ER-Diagramm ist das die Entität, die so ähnlich wie eine Klasse ist, und *einen* Datensatz beschreibt. `nachricht` ist auch komischer Name für die Daten die dort gespeichert werden‽

Die Funktion zum Hinzufügen eines DB-EIntrags braucht die Werte als Argumente und die muss man beim Aufrufen dann auch übergeben.

Was soll das `_temp` bei den `StringVar`-Objekten? Da wird doch keine Temperatur gespeichert.

Die Fenstergrösse gibt man nicht pixelgenau vor. Da weiss man doch gar nicht ob da alles reinpassen wird, oder ob unnötig viel Leerraum bleiben wird. Die Fenstergrösse ergibt sich automatisch aus dem Fensterinhalt.

Die Widgetbreite ist eine Zahl und sollte auch als solche angegeben werden, solange man da keine Einheit mit angeben will.

Die ganzen `Label` und `Entry`-Objekte braucht man nicht an einen Namen binden.

Ungetestet und immer noch mit dem originalen SQL-Fehler, den man zu sehen bekommt wenn man das Programm von der Konsole aus startet:

Code: Alles auswählen

import tkinter as tk
from contextlib import closing

import mysql.connector


def insert_pupil(vorname, name, ort):
    with closing(
        mysql.connector.connect(
            user="root",
            password="******",
            host="127.0.0.1",
            port=3306,
            database="login",
            auth_plugin="mysql_native_password",
        )
    ) as connection:
        with closing(connection.cursor()) as cursor:
            #
            # Kann sein, dass ? nicht der richtige Platzhalter für
            # `mysql.connector` ist.  Bitte in der Dokumentation nachlesen.
            #
            cursor.execute(
                "INSERT INTO nachricht (vorname, name, ort) VALUES (?, ?, ?",
                [vorname, name, ort],
            )
            connection.commit()


def show_add_pupil_window():
    vorname_var = tk.StringVar()
    name_var = tk.StringVar()
    wohnort_var = tk.StringVar()

    window = tk.Toplevel()
    window.title("Schüler Liste (Hinzufügen)")
    tk.Label(window, text="Shool List Update", width=100).grid(
        row=0, column=0, pady=40
    )

    tk.Label(window, text="Vorname des Schülers").grid()
    tk.Entry(window, width=40, textvariable=vorname_var).grid()

    tk.Label(window, text="Name des Schülers").grid()
    tk.Entry(window, width=40, textvariable=name_var).grid()

    tk.Label(window, text="Wohnort des Schülers").grid()
    tk.Entry(window, width=40, textvariable=wohnort_var).grid()

    tk.Button(
        window,
        text="Hinzufügen",
        command=lambda: insert_pupil(
            vorname_var.get(), name_var.get(), wohnort_var.get()
        ),
    ).grid(pady=40)
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Erstmal danke für die Antwort und der guten Dokumentation. Ich habe es so aus einen Buch entnommen .

Ich versuche es mal so wie es da jetzt steht was Sie geschrieben haben.

Danke erstmal für die schnelle Antwort
Achso

Sie schrieben noch das hier

# Kann sein, dass ? nicht der richtige Platzhalter für
# `mysql.connector` ist. Bitte in der Dokumentation nachlesen.
#
Was meinen Sie damit ?
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Bitte in der Dokumentation nachlesen bedeutet, in der Dokumentation nachlesen: https://dev.mysql.com/doc/connector-pyt ... ecute.html

Zu Pythonmodulen gibt es meist eine Dokumentation, in der steht, wie man das Modul benutzen kann.
Korrekt wäre also:

Code: Alles auswählen

            cursor.execute(
                "INSERT INTO nachricht (vorname, name, ort) VALUES (%s, %s, %s)",
                [vorname, name, ort],
            )
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Achso das war damit gemeint .
Danke Ihnen und ein schönes Wochenende!
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Ich muss noch einmal stören , ich habe es mal selbst versucht es jetzt anders zu machen , also verbinndung zu Datenbank steht und funzt aber
wenn ich den Eintrag Abschicke kommt .

mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''nachrichten' ('vorname','name','ort') VALUES ('Arian','Kauschik','Duisburg Rahm' at line 1

Weiß einer was das bedeuten soll ?
Ich ging davon aus oder denke das ein Syntacs falsch ist .

Ich weiß nicht ob der den mysql_connector meint aber den nehmen alle ja soweit .
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie sieht der Code dazu aus? Falsches SQL hat nichts mit der Python-Bibliothek zu tun, die Du nutzt. SQL ist eine eigene Sprache, neben Python, die Du lernen mußt.
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Sirius3 hat geschrieben: Donnerstag 13. Februar 2025, 21:19 Wie sieht der Code dazu aus? Falsches SQL hat nichts mit der Python-Bibliothek zu tun, die Du nutzt. SQL ist eine eigene Sprache, neben Python, die Du lernen mußt.

Code: Alles auswählen

import tkinter as tk
from tkinter import StringVar
import mysql
import mysql.connector

root = tk.Tk()







def hinzu_window():
    def click_send():
        conn = mysql.connector.connect(host="127.0.0.1", user="root", password="Password@123", database="login",
                                       port="3306")
        c = conn.cursor()

        firstname = "Thorsten"
        name = "hanzen"
        city = "Duisburg"

        insert_query = "INSERT INTO 'nachrichten' ('vorname','name','ort') VALUES (%s,%s,%s)"
        vals = (firstname, name, city)
        c.execute(insert_query, vals)
        conn.commit()
        conn.close()
        return






    extra_window = tk.Toplevel()
    extra_window.title("Schüler Liste (Hinzufügen")
    extra_window.geometry("900x650")

    user_info = tk.Label(extra_window,text="Shool List Update")
    user_info.grid(row=0,column=0,pady=40)
    user_info.configure(width="100")
    firstname_label = tk.Label(extra_window,text="Vorname des Schülers")
    firstname_label.grid()
    firstname_entry = tk.Entry(extra_window,width="40")
    firstname_entry.grid()
    name_label = tk.Label(extra_window, text="Name des Schülers")
    name_label.grid()
    name_entry = tk.Entry(extra_window, width="40")
    name_entry.grid()
    Wohnort_label = tk.Label(extra_window, text="Wohnort des Schülers")
    Wohnort_label.grid()
    wohnort_entry = tk.Entry(extra_window, width="40")
    wohnort_entry.grid()
    buttonlabel = tk.Button(extra_window,text="Hinzufügen", command=click_send).grid()


Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Mir ist nicht bekannt, dass Tabellennamen oder Spaltennamen in SQL-Statements in Hochkommata gesetzt werden.
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Meinst Du damit zb die Tabelle Nachrichten nicht in hochkomma setzen ? Sowie nach der Tabelle die Werte auch ohne hochkomma? Habe ich das so Richtig verstanden?

Lg
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@TorstenVoelker: Wo hast Du das denn her? Welche Quelle benutzt Du um SQL zu lernen?
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Connector/Python Revealed: So heißt das Buch ansonsten von you eine ein paar Tutorials.
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

sparrow hat geschrieben: Donnerstag 13. Februar 2025, 22:05 Mir ist nicht bekannt, dass Tabellennamen oder Spaltennamen in SQL-Statements in Hochkommata gesetzt werden.
Es hat geklappt, war ein Syntax Fehler

Danke dafür
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@TorstenVoelker: Das Buch eignet sich nicht wirklich um SQL zu lernen, das richtet sich an Leute, die MySQL und Python über das `mysql.connector`-Package verwenden wollen, und Python und (relationale) Datenbanken und SQL schon können. Steht auch so in der Einführung unter „Book Audience“.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Benutzeravatar
grubenfox
User
Beiträge: 612
Registriert: Freitag 2. Dezember 2022, 15:49

vielleicht hier: ein Link auf lehmanns.de SQL für Dummies
Wobei ich zur dortigen aktuellen 8. Auflage nichts sagen kann. Hinter mir liegt nur die 2. Auflage von 2001... keine Ahnung was sich in der Zwischenzeit so bei SQL getan hat. Aber die Grundlagen dürften immer noch identisch sein.
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

grubenfox hat geschrieben: Freitag 14. Februar 2025, 11:52 vielleicht hier: ein Link auf lehmanns.de SQL für Dummies
Wobei ich zur dortigen aktuellen 8. Auflage nichts sagen kann. Hinter mir liegt nur die 2. Auflage von 2001... keine Ahnung was sich in der Zwischenzeit so bei SQL getan hat. Aber die Grundlagen dürften immer noch identisch sein.
Danke , werde ich mir mal bestellen und mal schauen .
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Ich mache ja einiges mit PHP und mysqli nur das in Python die Abfragen anders aussehen also der Code . Das muss ich mir unbedingt an eignen.
Benutzeravatar
noisefloor
User
Beiträge: 4190
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Wobei das am SQL an sich sich doch nicht ändert. Auch in Python ist das SQL so, wie du es z.B. auch ins CLI von MySQL eintippen würdest. Außer halt die Platzhalter, die die Python DB API 2.0 vorgibt.

Und weil's noch keiner gesagt hat: bei der Programmierung von GUIs in Python z.B. mit tkinter immer mit Klassen arbeiten, außer bei mega-trivialen GUIs. Alles andere ist kein brauchbarer und wartbarer Ansatz. Beispiele findest du z.B. unter https://docs.python.org/3/library/tkinter.html ziemlich am Ende.

Gruß, noisefloor
TorstenVoelker
User
Beiträge: 142
Registriert: Mittwoch 5. Februar 2025, 12:55

Hallo Ihr lieben , ich habe mich gestern lange mit dek Thema Lamda beschäftigt und habe versucht mal selber was zu machen.
Einfach ein Test .

Ich weiß viele werden jetzt sagen , mach es doch mit with und und aber zum Testen wollte ich es schnell mal selber versuchen .

Wenn ich aud Senden gehe kommt ein Fehler und weiß nicht was er genau von mir will .

Kann mir einer bitte sagen wo der Fehler liegt ?


Danke im Vorraus

Code: Alles auswählen

import tkinter as tk
from tkinter import StringVar
import mysql.connector
from tkinter import messagebox
from contextlib import closing



def show(name):

    conn = mysql.connector.connect(
        host="127.0.0.1",
        user="root",
        password="password@123",
        database="login",
        auth_plugin="mysql_native_password")

    my_cursor = conn.cursor()
    my_cursor.execute("INSERT INTO bank (kontoname) VALUES (%s", [name])
    conn.commit()
    messagebox.showinfo("Erfolgreich","Wurde erfolgreich hinzugefügt")
    conn.close()















class MainMenue(tk.Tk):
    def __init__(self):
        super().__init__()

        name = StringVar()

        self.geometry("300x300")
        self.title("Hallo Du")


        self.labeltext = tk.Label(self,text="Bitte gebe einen Namen ein")
        self.labeltext.pack()

        self.labelentry = tk.Entry(self,width=20,textvariable=name)
        self.labelentry.pack()

        self.btn = tk.Button(self,text="Absenden",command=lambda: show(name.get()) )
        self.btn.pack()




root = MainMenue()
root.mainloop()

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

jetzt wäre es noch hilfreich, wenn Du auch die Fehlermeldung posten würdest, damit wir nicht raten müssen, was denn falsch läuft. Zu jeder öffnenden Klammer gehört auch eine schließende.
Antworten