GUI – 38 Eingabefelder und 38 Beschriftungen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hello again!

Der SQL-String wird jetzt korrekt erstellt. Ich bin schon beim nächsten Problem:

Ein SQL-Befehl
INSERT INTO dauner (taetig_in_firma, ort_stadt, name_oder_firmenname) VALUES ('Test', 'Test', 'Test')
wird korrekt ausgegeben. Aber die Methode

Code: Alles auswählen

cursor.execute(sql_abfrage_string)
ist ohne Wirkung; der Tabelle wird kein Datensatz/Tupel hinzugefügt. Allerdings erscheint auch keinerlei Fehlermeldung. Erbitte Hilfe.

Grüße
Strawk
:)
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

COMMIT ist dein Freund. Bzw connection.commit()
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: wenn Dein execute beim SELECT so aussieht, wie beim INSERT, wird der SQL-String nicht korrekt erstellt. Du willst anscheinend keine Hilfe, weil Du Deinen Code so verheimlichst und auf Anmerkungen nicht reagierst.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Kann ich euch den Gesamtcode als ZIP-Datei hochladen?

Grüße
Strawk
:D
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du koenntest github bemuehen. Oder pastebin. ZIP ist aetzend, weil man mehrere Schritte gehen muss, um es zu betrachten, und das dann nicht mehr im Browser.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Bitte ganz kurze Hilfe zur Selbsthilfe. Über die SQL-Abfrage
SELECT * from dauner where nummer = 33
und den Code

Code: Alles auswählen

werte = []
    for eintrag in sql_ergebnis:
        werte.append(eintrag)   
    print werte
erhalte ich das Ergebnis
[(33.0, u'inl-s', u'Beck', u'', u'Martina', u'Pariser Ring 319', u'52066', u'Herzogenrath', u'Eilendorf', u'Niedersachsen', u'\xd6sterreich', u'Renault', u'', u'', u'026', u'0211', u'9367833', u'ja', u'01512', u'89594265', u'martin.koenigs@gmx.de', u'wq4567@philip-leisten20.de', u'www.britih_petroleum.de', u'weiblich', 0, None, datetime.datetime(1959, 1, 1, 12, 0), 0, u'', u'02111239875', u'kein', u'', u'Assistent', u'Redaktionspraktikant', u'Fritten Heini', u'h\xe4keln', u'Tschetschenien', datetime.datetime(1999, 1, 1, 12, 0))]
Wie kann ich das Ergebnis auf die reinen Werte beschränken, also ohne die Felddatentypen?

Grüße
Strawk
:D
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das sind die reinen Typen. Du kannst die zu strings formatieren.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo __deets__!

Hättest du die Güte, mir zu sagen, wie?

Grüße
Strawk
:?:
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Hättest du die Güte, mir zu sagen, wie?
Steht alles im Python-Tutorial :-)

Die Wandlung willst du so wie so erst machen, wenn du die Daten ausgibst. Solange die mit den Daten intern hantierst, solltest du diese Datentypen behalten.

Wenn du z.B. Unicode-Strings per `print` Statement ausgibst, dann erscheint das so, wie du es erwartest:

[codebox=pycon file=Unbenannt.txt]>>> a = u'h\xe4keln'
>>> print a
häkeln[/code]

Noch was: die SQL-Abfrage liefert dir bereits eine Liste von Tupeln. Warum iterierst du über die Liste, nur um diese in einen neue Liste zu packen? Das kannst du dir auch sparen...

Gruß, noisefloor
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Anhand der Nummer (PRIMARY KEY) soll ein einziger Datensatz in die Maske eingelesen werden. Es werden aber nur vier Werte eingelesen. Siehe Bild.

https://www.pic-upload.de/view-34520209 ... 4.jpg.html

Hier der entsprechende Code:

Code: Alles auswählen

def buttonLiesInMaskeEinClick():
    felder = ["nummer", "codierung",
              "name_oder_firmenname", "geburtsname", "vorname_bezeichnung",
              "strasse_hausnummer", "plz", "ort_stadt",
              "ortsteil", "bundesland_provinz_kanton", "land_nation",
              "fahrzeugfabrikat", "fahrzeugtyp", "kfz_kennzeichen_historie",
              "landesvorwahl", "festnetzvorwahl", "festnetznummer",
              "aktiv", "mobile_vorwahl", "mobiler_anschluss",
              "e_mail_1", "e_mail_2", "url",
              "geschlecht", "anzahl_kinder", "verstorben_am_um",
              "geburtstag", "anzahl_ereignisse", "memos",
              "fax", "titel", "beruf",
              "ausbildung", "taetigkeit", "taetig_in_firma",
              "hobbys", "herkunftsland", "bekanntschaft_seit"]
    nummer_gesucht = nummer.get()
    sql_ergebnis = in_Maske_einlesen.inMaskeEinlesen(nummer_gesucht)
       
    werte = []
    for eintrag in sql_ergebnis:
        for x in eintrag:
            werte.append(x)
        
    dictionary = dict(zip(felder, werte))
    
    for key, value in dictionary.items():
        key = eval(key)
        key.insert(END, value)

Code: Alles auswählen

import zugriff

def inMaskeEinlesen(nummer):
    zugriffsnummer = nummer
    print zugriffsnummer
    connection = zugriff.zugriff()
    cursor = connection.cursor(buffered=True)
    abfrage  = "SELECT * from dauner where nummer = " + zugriffsnummer
    print abfrage
    cursor.execute(abfrage)
    sql_ergebnis = cursor.fetchall()

    # Execution-Objekt schließen
    cursor.close()

    # Verbindung schließen
    connection.close()
    
    return sql_ergebnis
Warum gerade diese vier und die anderen nicht?

Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Strawk: wie oft sollen wir Dir eigentlich noch sagen, dass so, wie Du programmierst, alles sehr fragil ist und Dir bei der ersten kleinen Änderung um die Ohren fliegt?

In `inMaskeEinlesen` formatierst Du eine Zahl, die als String an die Funktion übergeben werden muß, direkt in eine SQL-Abfrage, die auch noch ein * enthält.
1. nie direkt Parameter zu SQL-Befehle zusammenstückeln.
- bei nummer erwartet jeder, dass er eine Zahl übergeben könnte, funktioniert aber nur mit Strings.
- Wenn Du die nummer direkt aus einer Eingabemaske liest, hat jeder komplette Kontrolle über Deine Datenbank und kann sie, auch unabsichtlich, komplett kaputt machen.
- ist es einfach nur viel umständlicher, als es richtig zu machen.
2. Das * liefert dir die Spalten in einer Reihenfolge, die irgendwo intern in der Datenbank definiert ist. Wenn sich da was ändert, passen die Spalten nicht mehr zu der Liste, die Du irgendwo anders definiert hast. Von der Wartungsseite her ist das also eine Katastrophe.
Warum nennst Du `nummer` in `zugriffsnummer` um? Wie viele Ergebnisse erwartest Du, wenn jeder Eintrag eine eindeutige Nummer hat? `inMaskeEinlesen` ist der falsche Name, weil hier nichts in irgendeine Maske gelesen wird.

In `buttonLiesInMaskeEinClick` definierst Du irgendwelche Felder, die Du sicher noch an 7 anderen Stellen auch brauchst, das ist also eine Konstante, die an einen globalen Ort gehört. `nummer` kommt aus dem Nichts. Alles was eine Funktion braucht, sollte sie als Parameter bekommen. Bei GUIs mit Zustand, wird das meist über Klassen gelöst, GUI ohne OOP geht eigentlich nicht.
Für `sql_ergebnis` ist es eigentlich egal, woher die Daten kamen, wichtig ist, was die Variable enthält.
Zeile 19: nochmal, wie viele Ergebnisse erwartest Du, wie viele Felder hast Du, und was passiert, wenn doch mehr Ergebnisse geliefert werden als erwartet?
Zeile 23: diese Zeile sollte schon in der Funktion mit der SQL-Abfrage stehen.
Zeile 26: das ist der Grund, warum nichts funktioniert. Niemals `eval` benutzen. Hier wurde Dir schon mehrmals gesagt, pack die Eingabefelder in Listen oder Wörterbücher, oder sonst was.

Also, nimm mein Beispiel von vor drei Wochen. Das ist ein guter Einstieg in die Art und Weise, wie Du Dein Programm aufbauen solltest. Lies in der Dokumentation nach, wie man richtig SQL-Abfragen schreibt. Lerne OOP.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Guten Tag, Sirius3!

Vielen Dank für deinen engagierten, langen Text. Zeit, die Segel zu streichen. :(

Ich lerne gern anhand von Büchern. Hier zu Hause (antiquarisch bestellt für € 70,-- :( ) habe ich:
Farid Hajji: Das Python Praxisbuch. Der große Profi-Leitfaden für Programmierer. München: Addison-Wesley 2008. (Open Source Library)
Da ist der Pfeil auf dem Spektrum "Einsteiger - Fortgeschrittene - Profis" aber weit rechts bei Profis; das ist wohl noch zu schwer für mich.

Hast du einen Buchtipp? Ein Werk, das hautsächlich bzw. insbesondere SQL-Datenbanken mit Python und GUI mit Python behandelt?

Viele liebe Grüße
Strawk
:(
Ich programmiere erfolglos, also bin ich nicht.
narpfel
User
Beiträge: 643
Registriert: Freitag 20. Oktober 2017, 16:10

@Strawk: Versuch’ einfach mal, eine Person mit dem Namen „Robert'); DROP TABLE dauner; -- Roberts“ (natürlich ohne die Anführungszeichen) anzulegen. Nachdem du ein Backup der Datenbank angelegt hast. :wink:
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@strawk: du brauchst nicht die Segel streichen - du musst nur mal _vernünftig_ von Grund auf Lernen. Python Anfänger + GUI + SQL-DB ist nun mal keine gute Idee. Und vielleicht nicht direkt mit 38 Feldern anfangen. Sagte ich aber bereits schon mal...

Zum Thema Buch: gibt es nicht, würde ich mal behaupten. Das Thema ist zu speziell. Selbst zu Zeiten, als Print-Medien noch wesentlich populärer waren als heute, wäre das wohl zu speziell gewesen.
Im Prinzip brauchst du auch kein Buch, was beides behandelt. Die GUI interagiert ja nicht mit der Datenbank direkt. Du hast ja immer einen "Übergabepunkt" für die Daten dazwischen.

Gruß, noisefloor
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

Morgen bekomme ich einen Raspberry Pi-Computer geschenkt; damit kann ich dann das letzte Kapitel von
THEIS, Thomas: Einstieg in Python. Ideal für Programmieranfänger. – Bonn: Rheinwerk Verlag GmbH 5., aktualisierte Auflage 2017 (4525)
bearbeiten, wonach ich dieses Buch dann durch habe.
Farid Hajji: Das Python Praxisbuch. Der große Profi-Leitfaden für Programmierer. München: Addison-Wesley 2008. (Open Source Library)
ist wohl, wie gesagt, noch zu schwer, da für Profis geschrieben.
Wie also soll es denn nun für mich weitergehen?

Gruß
Strawk
Ich programmiere erfolglos, also bin ich nicht.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Wie also soll es denn nun für mich weitergehen?
1. Offizielles Python-Tutorial durcharbeiten. Danach solltest du die Grundlagen drauf haben.
2. DB-Teil programmieren, so dass du sauber Daten schreiben und Lesen kannst.
3. GUI angehen mit _weniger_ Felder, sagen wir 3-5

Und natürlich am besten hier im Forum den Code immer wieder vorstellen, Kritik abholen, besser werden :-)

Und wenn das alles sauber läuft, die GUI auf 38 Felder aufbohren.

Und falls du erwartest, dass du das alles mit deutschsprachiger Literatur / Webseiten hin bekommst: vergiß' es. Englisch ist nun mal die Standardsprache und auf Englisch findest du auch viiiiiiiiiel mehr Webseiten, Lösungsansätze etc. (z.B. bei Stack Overflow).

Gruß, noisefloor
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich finde die Argumentation etwas schräg. Du kannst doch nicht programmieren, nur weil du ein Buch durchgelesen hast. Jedes Fachbuch das ich kenne, muss man durcharbeiten. Ggf mehrfach. Es gab diverse Themen hier, bei denen wir dir Hilfestellung angedeihen lassen mussten, obwohl das Thema in deinem Buch behandelt wurde. War aber nicht auf Pfanne. Was ja nicht schlimm ist. Zeigt nur, das du dich durchaus wieder beschäftigen kannst. ZB Kapitel 5.2 zur String Formatierung.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Strawk hat geschrieben:Farid Hajji: Das Python Praxisbuch. Der große Profi-Leitfaden für Programmierer. München: Addison-Wesley 2008. (Open Source Library)

ist wohl, wie gesagt, noch zu schwer, da für Profis geschrieben.
Das Buch ist eigentlich ganz gut gelungen, ist aber eben auch von 2008 und bezieht sich auf das damals aktuelle Python 2.5. Das zu dem Zeitpunkt neue with-Statement hatte es wohl nicht mehr in das Manuskript geschafft und das einführende Hello-World Beispiel nutzt in der tkinter-Variante ein 'global', vermutlich da OOP erst später behandelt wird. Bis Kapitel 10 ist das Buch meiner Meinung nach durchaus für Anfänger geeignet – in dem Bewusstsein, dass es bereits 10 Jahre alt ist und sich die Sprache seitdem weiterentwickelt hat.

In der rein prozeduralen Programmierung war die Nutzung von 'global' häufig anzutreffen, auch auf die Gefahr hin, ein Programm fehlerhaft und unwartbar zu machen. In Python sind globale Variable glücklicherweise vermeidbar. Beachte dies bitte, wenn Du Deinen Raspi bekommst und Hilfe in Raspi-Foren suchen solltest. Dort erhalten globals mittlerweile wieder ein zweites Leben.
Benutzeravatar
Strawk
User
Beiträge: 227
Registriert: Mittwoch 15. Februar 2017, 11:42
Wohnort: Aachen
Kontaktdaten:

Hallo!

@noisefloor
Offizielles Python-Tutorial durcharbeiten. Danach solltest du die Grundlagen drauf haben.
Dieses hier?
https://docs.python.org/3/tutorial/

Grüße
Strawk
Ich programmiere erfolglos, also bin ich nicht.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja.
Antworten