Tkinter: Falsche Anordnung in my_tree nach Schließung der Anwendung

Fragen zu Tkinter.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Selbst wenn man den ORM-Teil von SQLAlchemy nicht verwenden möchte, bügelt das ja die Unterscheide zwischen den DBMS glatt und erleichtert es dynamisch Anfangen zusammen zu basteln, ohne auf Zeichenkettenoperationen zurückgreifen zu müssen.

Mein letztes Beispiel ohne ORM (ungetestet):

Code: Alles auswählen

import tkinter as tk
from tkinter import messagebox

from sqlalchemy import (
    INT,
    VARCHAR,
    Column,
    MetaData,
    Table,
    delete,
    insert,
    select,
)

META_DATA = MetaData()
STUDENT_TABLE = Table(
    "dbo.student",
    META_DATA,
    Column("id", INT, primary_key=True),
    Column("firstname", VARCHAR, nullable=False),
    Column("lastname", VARCHAR, nullable=False),
    Column("address", VARCHAR, nullable=False),
)


def create_student_table(engine):
    STUDENT_TABLE.create(engine, checkfirst=True)
    print("Table 'Student' created succesfully.")


def add_student(db_connection, student_tree, textboxes):
    firstname, lastname, address = [
        textbox.get().strip() for textbox in textboxes
    ]
    if not all(firstname, lastname, address):
        messagebox.showinfo("Error", "Please fill out all the fields!")
    else:
        try:
            result = db_connection.execute(
                insert(STUDENT_TABLE).values(
                    firstname=firstname, lastname=lastname, address=address
                )
            )
            db_connection.commit()
        except Exception as error:
            messagebox.showinfo("Error", f"Failed to add data: {error}")
        else:
            messagebox.showinfo("Data added succesfully!")
            student_tree.insert(
                "",
                tk.END,
                values=(
                    result.inserted_primary_key.id,
                    firstname,
                    lastname,
                    address,
                ),
            )


def del_student(db_connection, student_tree):
    selection = student_tree.focus()
    if selection:
        delete(STUDENT_TABLE).where(
            STUDENT_TABLE.c.id
            == int(student_tree.item(selection)["values"][0])
        )
        db_connection.commit()
        student_tree.delete(selection)


def load_students(db_connection, student_tree):
    for student in db_connection.execute(select(STUDENT_TABLE)):
        student_tree.insert(
            "",
            tk.END,
            values=(
                student.id,
                student.firstname,
                student.lastname,
                student.address,
            ),
        )
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

@__blackjack__ : schaue mir dann mal SqlAlchemy an

@sparrow: bei deinem code kriege ich diese meldung:


Traceback (most recent call last):
File "C:\Users\mago\PycharmProjects\Projects\main.py", line 135, in <module>
main()
File "C:\Users\mago\PycharmProjects\Projects\main.py", line 129, in main
create_student_table(db_connection)
File "C:\Users\mago\PycharmProjects\Projects\main.py", line 30, in create_student_table
cursor.execute(SQL_CREATE_STUDENT_TABLE)
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near the keyword 'IF'. (156) (SQLExecDirectW); [42000] [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near 'Student'. (102)")
Sirius3
User
Beiträge: 17712
Registriert: Sonntag 21. Oktober 2012, 17:20

@magocode: muß man Dir alles vorkauen?

Code: Alles auswählen

SQL_CREATE_STUDENT_TABLE = """ 
IF OBJECT_ID(N'Student', N'U') IS NULL
    CREATE TABLE Student (
        student_id INT PRIMARY KEY,
        firstname VARCHAR NOT NULL,
        lastname VARCHAR NOT NULL,
        address VARCHAR NOT NULL
    )
GO
"""
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

@Sirius3: wenn du gut kauen kannst :) , ich bin euch wirklich dankbar aber bin ein anfänger, dein code geht immer noch nicht , du hast hier ja auch nur das if not exist weggelassen ? ich versuche es mal heute alleine und melde mich morgen wieder
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@magocode: Das ist nicht von Sirius3, der hat den SQL-Code von sparrow nur in eine Zeichenkette getan und an einen Namen gebunden. Und da ist nicht einfach nur das IF NOT EXIST weg gelassen. Da ist ein neues IF und ein GO dazu gekommen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

blackjack: das ist doch der vorherige code, ich sehe nur den unterschied mit "if not exist", wo sieht man das ein neues if dazugekommen ist?

Code: Alles auswählen

SQL_CREATE_STUDENT_TABLE = """ 
IF OBJECT_ID(N'Student', N'U') IS NULL
    CREATE TABLE IF NOT EXIST Student (
        student_id INT PRIMARY KEY,
        firstname VARCHAR NOT NULL,
        lastname VARCHAR NOT NULL,
        address VARCHAR NOT NULL
    )
GO
"""
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

@magocode: Und wo steht in dem Beitrag von Sirius3 "IF NOT EXIST?"
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

verständnisfrage: die zeile: "IF OBJECT_ID(N'Student', N'U') IS NULL" überprüft doch schon ob die tabelle nicht existiert und wird nur dann aufgerufen, wieso war es dann nötig nochmal "create table if not exist Student" zu machen ?
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

@magocode: Liest du die Beiträge? Sirius3 hat doch mein Statement bereits korrigiert.
Und ja, dein Verständnis ist richtig.
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

@sparrow: hatte es überlesen, ok danke.
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

Hab das GO weggelassen und es geht jetzt in dem Sinne dass die Anwendung geöffnet wird, ich mit einer Fehlermeldung die Daten in die my_tree bekomme aber trotz Nachricht "table student created " im terminal, wird in der db keine tabelle erstellt.
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

Fehlermeldung: "Failed to add data ....Microsoft SQL Server.. String or binary data would be truncated in table 'MANAGEMENT.dbo.Studet', column 'firstname'. Truncated value: 'D'. (2628)SQLExecDirect....... SQL Server.. The Statement has been terminated (3621).
Meine Testeingabe: 22, De , Re , Ds (id, firstname, lastname, address)
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

Hab Fehler gefunden, hab hinter VARCHAR die 50 geschrieben um es kurz zu fassen. Alles funktioniert jetzt , Danke und bis zu der nächsten Frage :)
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@magocode Da schaut man dann mal in die Dokumentation von SQL-Server und stellt fest, dass VARCHAR als Defaultlänge *1* verwendet. Da würde ich dann mal schauen ob TEXT oder NTEXT nicht vielleicht besser geeignet sind.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
magocode
User
Beiträge: 24
Registriert: Dienstag 9. Mai 2023, 08:53

merke ich mir für die nächste anwendung, versuche nochmal anders csv importer.
Benutzeravatar
grubenfox
User
Beiträge: 414
Registriert: Freitag 2. Dezember 2022, 15:49

__blackjack__ hat geschrieben: Donnerstag 8. Juni 2023, 14:49 @magocode Da schaut man dann mal in die Dokumentation von SQL-Server und stellt fest, dass VARCHAR als Defaultlänge *1* verwendet. Da würde ich dann mal schauen ob TEXT oder NTEXT nicht vielleicht besser geeignet sind.
... um dann zu entscheiden TEXT bzw. NTEXT lieber nicht zu nehmen. Unter anderem weil die bei Microsoft schon über 10 Jahre als "veraltet" markiert sind https://docs.sqlalchemy.org/en/20/diale ... eprecation. Entsprechend werden sie von SQLAlchemy wahlweise unterstützt oder auch nicht.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Vielleicht noch ein Grund SQLAlchemy zu verwenden und dort dann die „CamelCase“-Datentypen um SQLAlchemy den jeweils besten Typ für das konkrete DBMS auswählen zu lassen. Also beispielsweise `UnicodeText`. Ich benutze die viel zu selten weil ich meistens Code schreibe, der an bereits bestehende Datenbanken ran geht, und ich dort dann reflection benutze und/oder die konkreten „UPPERCASE“-Datentypen wie sie in der DB schon definiert sind.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
sparrow
User
Beiträge: 4165
Registriert: Freitag 17. April 2009, 10:28

Und gerade bei MS SQL ist das unglaublich hilfreich, weil die ihren SQL-Kram sehr... speziell machen.
Da lobe ich mir jedes Arbeiten mit Postgres.
Antworten