Abfrage SQlite Datenbank

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

Das mit dem except versteh ich ja noch, dadurch wird einfach jeder Fehler abgefangen und man sieht nichts und es würde auch nichts passieren!

Gut aber wie müsste ich den try denn sonst aufbauen damit der Code noch weiter ausgeführt wird...

Ich verstehe auch nicht, wie ich meine Wörterbücher reduzieren könnte...
BlackJack

@sveni_lee: An dem ``try``-Block brauchst Du nichts ändern. Von ``except`` habe ich allerdings in dem Zusammenhang nichts geschrieben. Dafür aber von ``finally``, was Du aber nirgends verwendet hast.

Du hast ganz offensichtlich nicht verstanden/nachvollzogen was der Ausdruck von Sirius3 macht, sondern ihn einfach auf gut Glück in Deinen Code reingeschrieben. Mach Dir klar was da passiert, dann weisst Du auch wie man den *richtig* in Deinen Code integriert.

Ich denke nicht, dass SQLAlchemy die Komplexität an der Stelle tatsächlich stark erhöht, auf jeden Fall wird es deutlich weniger fehleranfällig, weil es schwerer wird kaputtes SQL zu erstellen. Was bei manuellem zusammenbasteln auf Zeichenkettenebene schnell geht. Und lesbarer wird es IMHO auch.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

BlackJack hat geschrieben: Du hast ganz offensichtlich nicht verstanden/nachvollzogen was der Ausdruck von Sirius3 macht, sondern ihn einfach auf gut Glück in Deinen Code reingeschrieben. Mach Dir klar was da passiert, dann weisst Du auch wie man den *richtig* in Deinen Code integriert.
Also der Ausdruck setzt meine Werte aus der Liste propertys in ein dictionary mit den Werten aus der SQL Datenbank und baut daraus dann wieder eine Liste... Ich das Ergebniss des Ausdrucks gedegugged und es ist genau der Aufbau den ich für die Weiterverarbeitung bebötige.
Ich denke nicht, dass SQLAlchemy die Komplexität an der Stelle tatsächlich stark erhöht, auf jeden Fall wird es deutlich weniger fehleranfällig, weil es schwerer wird kaputtes SQL zu erstellen. Was bei manuellem zusammenbasteln auf Zeichenkettenebene schnell geht. Und lesbarer wird es IMHO auch.
Okay auch das kann ich mir ansehen und ändern wenn ich das ganze mal richtig in KODI zum laufen gebracht habe.
BlackJack

@sveni_lee: Der Ausdruck „baut“ keine „Liste“. Die Liste die da am Ende heraus kommt, solltest Du Dir aber mal anschauen.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

BlackJack hat geschrieben:Die Liste die da am Ende heraus kommt, solltest Du Dir aber mal anschauen.
Das habe ich doch getan... Ich hatte doch geschreiben, das ich die Liste dann ins Log habe schreiben lassen um zu sehen wie sie aussieht.

in den {} ist jeweils ein datensatz vorhanden, die einzelnen Daten darin sind durch ``,`` von einander getrennt.
in der [] sind alle datensätze zusammengefasst.

Genau so sollte es aussehen damit ich es mit xbmcgui.ListItem() weiter verarbeiten kann...

Code: Alles auswählen

elif methode == 'get_item_serienplaner':
    sp_items = refreshWidget(__LS__(30116))
    writeLog('spitems %s' % (sp_items), level=xbmc.LOGDEBUG)
    url = '-'
    for sitem in sp_items:

        li = xbmcgui.ListItem()
        li.setProperty("channel", sitem['Channel'])
        li.setArt("Poster"), sitem['Poster']
        li.setProperty("plot", sitem['Description'])
        li.setProperty("staffel", sitem['Staffel'])
        li.setProperty("episode", sitem['Episode'])
        li.setProperty("starttime", sitem['Starttime'])
        li.setProperty("rating", sitem['Rating'])
        li.setProperty("senderlogo", sitem['Logo'])
        li.setProperty("genre", sitem['Genre'])
        li.setProperty("date", sitem['Datum'])
        li.setProperty("rumtime", sitem['RunningTime'])
        li.setProperty("studio", sitem['Studio'])
        li.setProperty("year", sitem['Jahr'])
        li.setProperty("altersfreigabe", sitem['Altersfreigabe'])
        li.setProperty("status", sitem['Status'])
        li.setProperty("label", sitem['Title'])
        li.setProperty("label2", sitem['TVShow'])
        li.setArt("thumb", sitem['Thumb'])
        xbmcplugin.addDirectoryItem(handle=addon_handle, url=url, listitem=li)
    xbmcplugin.endOfDirectory(addon_handle)
ich verstehe grad nicht, was daran so falsch ist...
BlackJack

@sveni_lee: Falsch daran ist, das diese Liste zu viele Wörterbücher enthält. Das sollte eigentlich auffallen. Oder der Quelltext den Du gezeigt hast, stimmt nicht mit dem überein, den Du tatsächlich verwendest.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

BlackJack hat geschrieben:@sveni_lee: Falsch daran ist, das diese Liste zu viele Wörterbücher enthält. Das sollte eigentlich auffallen. Oder der Quelltext den Du gezeigt hast, stimmt nicht mit dem überein, den Du tatsächlich verwendest.
ich bin mir nicht sicher was genau Du meinst...

Code: Alles auswählen

def refreshWidget(category, offset=0):

    listitems = []

    conn = sqlite3.connect(SerienPlaner)
    cur = conn.cursor()
    query = """SELECT %s
           FROM TVShowData
           WHERE julianday(_Starttime) + (_RunningTime / 24.0 / 60.0) > julianday('now', 'localtime')
           %s
           ORDER BY StartTime
           LIMIT 15"""
    if category == __LS__(30116):
        filter = ""
        parameters = ()
    else:
        filter = " AND WatchType = ?"
        parameters = (category,)        

    query = query % (','.join(properties), filter)
    cur.execute(query, parameters)
    try:
        for idx, data in enumerate(cur, offset):
            for field, item in zip(properties, data):     
            
                WINDOW.setProperty('SerienPlaner.%d.%s' % (idx, field), item)
            
                listitems.append(dict(zip(properties, data)))          

        return listitems
    finally:
    
        cur.execute("""DELETE FROM TVShowData WHERE julianday(_Starttime) + (_RunningTime / 24.0 / 60.0) < julianday('now', 'localtime')""")
        conn.commit()
        conn.close()
fallsu Das Wörterbuch "properties" vermisst, das habe ich Global abgelegt, da ich es auch an anderen stellen verwende...

Code: Alles auswählen

properties = ['TVShow', 'Staffel', 'Episode', 'Title', 'Starttime', 'Datum', 'neueEpisode', 'Channel', 'Logo', 'PVRID', 'Description', 'Rating', 'Altersfreigabe', 'Genre', 'Studio', 'Status', 'Jahr', 'Thumb', 'FirstAired', 'RunningTime', 'Poster', 'WatchType']
BlackJack

@sveni_lee: `listitems` ist falsch. Das ist zu lang. Weil Du da zu viele Wörterbücher rein steckst. Und zwar 22 mal mehr als drin sein sollten. Für jeden Datensatz hängst Du jeweils 22 gleiche Wörterbücher an. Wie kann so etwas nicht auffallen‽
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

BlackJack hat geschrieben:Für jeden Datensatz hängst Du jeweils 22 gleiche Wörterbücher an
jetzt sehe bzw. verstehe ich was Du meinst...
BlackJack hat geschrieben:Wie kann so etwas nicht auffallen
weil ich mir nur den ersten und den letzt Datensatz angesehen habe...

gut ich benötige alle Werte aus properties mit den dazugehörigen Daten aus der SQL für jeden abgefragten Datensatz.
Ich wüsste nicht welches Wörterbuch ich da jetzt weg lassen kann...
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@sveni_lee: ich würde jeweils das letzte der 22 gleichen Wörterbücher behalten und die 21 davor weglassen.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

Sirius3 hat geschrieben:ich würde jeweils das letzte der 22 gleichen Wörterbücher behalten und die 21 davor weglassen.
bei listen kann man das mit [-1] machen aber irgendwie funktioniert das hier nicht so einfach
BlackJack

@sveni_lee: Ich weiss nicht was Du mit [-1] machen willst. Du musst ganz einfach nicht 22 mal das gleiche Wörterbuch für jeden Datensatz erzeugen und anhängen sondern das nur einmal für jeden Datensatz machen. Dazu muss man eigentlich nur Schleifen verstanden haben. Und wenn man Schleifen nicht versteht, wann da welcher Code wie oft ausgeführt wird, dann sollte man noch keine KODI-Plugins schreiben, sondern sich erst einmal die Grundlagen erarbeiten.

So ein KODI-Plugin mit all den komplexen Schnittstellen und den schlechten Möglichkeiten mit dem Code, den man entwickelt, zu experimentieren weil das alles innerhalb von einer grossen Anwendung in einem Plugin-Rahmenwerk passiert, wo Testläufe oder interaktive Shells nicht so einfach sind, ist IMHO kein guter Weg eine Programmiersprache oder Programmieren generell zu lernen. An der Stelle sollte man schon unfallfrei mit Schleifen und Grunddatenstrukturen wie Listen und Wörterbüchern operieren können, was Dir nach eigenen Angaben schwer fällt.

Zum Programmieren lernen ist es hilfreich ein Ziel zu haben, um die Motivation nicht zu verlieren. Aber wenn das Ziel, für den Anfang, etwas zu hoch gesteckt ist, sollte man schauen ob man sich auf dem Weg dorthin, nicht Zwischenziele setzen sollte, um den Frust zu vermeiden, der sich einstellen kann, wenn man das eigentliche Ziel nur sehr mühsam zusammen frickeln kann, aber letztendlich gar nicht richtig versteht was man da macht, oder warum da etwas funktioniert, oder eben auch nicht funktioniert.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

ich habe jetzt mal einen Debug eingebaut und nur einen Datensatz ausgeben lassen

Code: Alles auswählen

11:28:20 T:7432 DEBUG: [plugin.program.serienplaner 0.0.1]: zip(properties, data): {'neueEpisode': u'', 'Thumb': u'http://www.thetvdb.com/banners/episodes/164541/4178791.jpg', 'Title': u'Das rote Notizbuch', 'Jahr': u'2010', 'Staffel': u'2', 'TVShow': u'Hawaii Five-0', 'Channel': u'Fox HD', 'Status': u'Continuing', 'Description': u'Der Bergungstaucher Blake Spencer wird ermordet, und Steve bem\xfcht sich mit seinem Team um die Aufkl\xe4rung des Falles. Zuerst vermuten sie, dass Blake ein Wrack mit wertvollen Goldm\xfcnzen gefunden und sich damit in Gefahr gebracht hat. Doch die Wahrheit sieht ganz anders aus. W\xe4hrend der Ermittlungen lernt Danny Dr. Asano, eine Museumskuratorin, kennen. Sie gef\xe4llt ihm auf Anhieb, und er l\xe4sst sich von Steve dazu \xfcberreden, sie um ein Date zu bitten ...', 'Poster': u'http://thetvdb.com/banners/posters/164541-1.jpg', 'FirstAired': u'2011-10-10', 'Studio': u'CBS', 'Genre': u'Crime', 'Episode': u'4', 'Starttime': u'10:50', 'Altersfreigabe': u'TV-14', 'Rating': u'7.6', 'WatchType': u'Internationale Serien', 'Datum': u'13.04.2016', 'RunningTime': u'45', 'Logo': u'image://G%3a%5cKodi%5cSenderlogos%5cfox%20hd.png/', 'PVRID': u'36'}
11:28:20 T:7432 DEBUG: Previous line repeats 21 times.
der Datensatz wird 21x wiederholt. wenn ich nun nur den letzten satz haben möchte muß ich also den letzten key aus den dictionary
nehmen oder... danach habe ich in den Dokumentationen mal gesucht...
und das gefunden...

Code: Alles auswählen

dict.keys()[-1]
oder bin ich damit auf dem Holzweg?
BlackJack

@sveni_lee: Ja damit bist Du auf dem Holzweg. In der Liste sollten gar nicht erst zu viele Einträge hinzugefügt werden. Wenn Du da 22 mal das gleiche drin hast ist es schon zu spät, dazu sollte es erst gar nicht kommen. Und wenn jeder Eintrag nur einmal drin ist, gibt es auch keinen Grund irgendwas mit dem Index -1 machen zu wollen um einen der 22 Datensätze zu bekommen, denn dann gibt es den ja nur einmal und man muss gar nichts an der Liste im nachhinein verändern.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

also sollen in die Liste jeweils nur der erste Datensatz in die Liste eingetragen werden, richtig?

also irgendwas in der Art?

Code: Alles auswählen

(zip(properties, data)[0])
BlackJack

@sveni_lee: Da sieht man jetzt wieder das Du *kein Stück* verstanden hast was der Code tut den Du da von anderen übernommen hast. Programmieren durch raten funktioniert nicht!

Es sollte nicht nur das erste, oder das letzte, oder irgendein anderes der Wörterbücher an die Liste angehängt werden, denn diese 22 Wörterbücher pro Datensatz sollten überhaupt gar nicht existieren. Die gibt es gar nicht wenn man es richtig macht, folglich braucht man sich auch nicht für eines davon zu entscheiden.

Es sollte pro Datensatz genau ein Wörterbuch erzeugt und angehängt werden. Und das machst Du nicht. Du hängst nicht pro Datensatz eines an, sondern pro… Und das solltest Du selber wissen/herausfinden, denn solange Du das nicht verstanden hast, hast Du Schleifen und den Programmablauf nicht verstanden, und auf dieser fehlenden Grundlage kann man nicht programmieren. So kannst Du nur abschreiben, raten, rumprobieren, ohne zu verstehen was Du da tust, und auch ohne überhaupt sicher zu sein, dass Du ein robustes, fehlerfreies Programm schreibst. Denn selbst wenn etwas scheinbar funktioniert, kann es trotzdem noch Fehler haben. Sieht man hier ja sehr schön wie lange Du der Meinung warst das wäre alles in Ordnung und den Fehler nicht gesehen hast. Nicht mal an den Daten obwohl der schon im Code offensichtlich ist. Und zwar nicht nur offensichtlich für langjährige Programmierer, sondern auch für Anfänger die wissen wie so etwas grundlegendes wie Schleifen funktionieren/abgearbeitet werden.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

BlackJack hat geschrieben:@sveni_lee: Da sieht man jetzt wieder das Du *kein Stück* verstanden hast was der Code tut den Du da von anderen übernommen hast. Programmieren durch raten funktioniert nicht!
das hat nicht raten oder sonstigem zu tun... ich versuche diese sachen durch literatur und internet heraus zufinden. Leider werden dort aber nur "hallo Word" Geschichten betrachtet. Ich habe das letzte mal mir BASIC auf einem KC87/2 programiert falls Dir das noch etwas sagt! Das 87 steht für das JAhr in dem er vorgestellt wurde... nur mal nebenbei. Ich betrachte das ganze als Hobby und versuche anhand von bestehen codeteilen etwas nachzuvollziehen. Was mir zugegebener Maßen nicht ganz gelingt!
Es sollte nicht nur das erste, oder das letzte, oder irgendein anderes der Wörterbücher an die Liste angehängt werden, denn diese 22 Wörterbücher pro Datensatz sollten überhaupt gar nicht existieren. Die gibt es gar nicht wenn man es richtig macht, folglich braucht man sich auch nicht für eines davon zu entscheiden.
Das ist mir schon klar, ich war mir bis heute nicht bewusst, das das über haubt so passiert...
Es sollte pro Datensatz genau ein Wörterbuch erzeugt und angehängt werden. Und das machst Du nicht. Du hängst nicht pro Datensatz eines an, sondern pro…
ich denke du meinst hier ...Eintrag im der liste properties, das würde bedeuten, das schon diese Schleife

Code: Alles auswählen

for field, item in zip(properties, data):
nicht richtig ist... so wie es dar steht soll er für jedes (field, item) in meiner liste property einen Datensatz erzeugen...
er soll aber aber nur einen Datensatz für alle daten in properties erzeugen...
Und das solltest Du selber wissen/herausfinden, denn solange Du das nicht verstanden hast, hast Du Schleifen und den Programmablauf nicht verstanden, und auf dieser fehlenden Grundlage kann man nicht programmieren. So kannst Du nur abschreiben, raten, rumprobieren, ohne zu verstehen was Du da tust, und auch ohne überhaupt sicher zu sein, dass Du ein robustes, fehlerfreies Programm schreibst. Denn selbst wenn etwas scheinbar funktioniert, kann es trotzdem noch Fehler haben. Sieht man hier ja sehr schön wie lange Du der Meinung warst das wäre alles in Ordnung und den Fehler nicht gesehen hast. Nicht mal an den Daten obwohl der schon im Code offensichtlich ist. Und zwar nicht nur offensichtlich für langjährige Programmierer, sondern auch für Anfänger die wissen wie so etwas grundlegendes wie Schleifen funktionieren/abgearbeitet werden.

ich habe nie erwartet das mir der fehlende Code auf einem Tabett serviert wird aber wäre schon nett gewesen zu sagen, dass ich mir die schleife mal genauer ansehen sollte und wie oft dort Datensätze gebildet werden...

Auch auf die gefahr hin, das ich nun keine Antwort mehr bekomme und ich das Projekt "sterben" lassen muss. möchte ich trotzdem noch einiges loswerden:
Wenn ich meinen Kindern versuchen würde ihnen auf diese Weise etwas beizubringen oder zuverdeutlichen würde ich damit nur erreichen, das sie frustriert aufgeben! Damit hätte ich mein Ziel verpfehlt!
Es ist wichtig Sie auf die Fehler aufmeksam zumachen und das nicht in kryptischen äußerungen sondern ganz konkret ihnen zeigen an welcher stelle die Fehler sind und wo etwas falsch verstanden wurde...

Zurück zum Thema:

Ich habe mir die sache noch einmal angesehen, ich müsste eine dict aus ``field`` und ``item``bilden richtig? oder auch wieder flasch?
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@sveni_lee: bei Deinen Kindern gehst Du hoffentlich auch davon aus, dass sie mit der Zeit einige Dinge selbständig erledigen können. Um bildlich zu bleiben, wenn sie ihre Jacke einfach liegen lassen, reicht ein "Jacke aufräumen" und man muß ihnen nicht zeigen, wo der Kleiderhaken ist.
for-Schleifen führen Dinge wiederholt aus. Wenn etwas zu oft ausgeführt wird, kann es vielleicht an einer for-Schleife liegen. Wenn Du weißt, was Deine for-Schleifen machen, ist auch klar, wie oft welches das Wörterbuch in der Liste landet. Bei einem Abschnitt, der aus 5 Zeilen besteht traue ich das beantworten dieser Frage auch einem Anfänger zu. Und über das dict aus field und item warst Du schon ganz am Anfang dieser Diskusion unglücklich.
sveni_lee
User
Beiträge: 92
Registriert: Montag 14. März 2016, 09:50

Naja, das mit dem Jacke aufräumen werden die beiden nie lernen... :P

Gut dann kann es ja nur an der Zweiten Schleife liegen... da wird für jedes item das eine Field aus der Liste hat ein kompletter Datensatz gebildet... Da ich 22 Werte in der Liste properties habe, werden dann wohl auch 22 Datensätze gebildet bis es zum nächsten idx aus der übergeordneten Schleife geht!

Die übergeordnete Schleife durchläuft ja nur die Anzahl der Ergebnisse aus der SQL Abfrage

Kommt das so hin?

Die SQL Abfrage ergibt ja eigendlich mehr als nur 22 Daten pro Datensatz...
BlackJack

@sveni_lee: Der KC87 konkret sagt mir nichts, aber das Jahr, 8-Bit-Rechner, und BASIC klingen sehr vertraut. Um die Zeit habe ich mit BASIC auf einem C64 angefangen. Ich habe im Netz ein Handbuch für das KC87-BASIC gefunden, und das sieht dem CBM BASIC recht ähnlich.

Ich denke ein wesentlicher Unterschied zwischen diesen BASIC-Dialekten und modernen Hochsprachen ist die Abstraktionsebene. Bei BASIC musste man sehr viel schreiben um eigentlich einfache Dinge zu erreichen, während moderne Programmiersprachen oft sehr ausdrucksstark sind, also bei wenig Code komplexe Dinge passieren. Das macht es schwieriger durch reines Anschauen, ohne nachzulesen und auszuprobieren, zu verstehen was Code macht. Und mit ausprobieren meine ich nicht wild herumprobieren, sondern sich zu überlegen was ein Ausdruck als Ergebnis hat, oder wie Code abgearbeitet wird und welche Effekte sich daraus ergeben, es dann ausführen und das Ergebnis mit der Erwartung vergleichen. Dann Änderungen ausprobieren, und dabei wieder vorher überlegen was hinten heraus kommen sollte. Und wenn die Erwartung nicht eintritt, dann überlegen warum das so ist.

Wie oft in den Schleifen Datensätze gebildet werden haben wir ja gesagt. Wenn jeder Datensatz 22 mal vorkommt, muss das ja irgendwo passieren, und wo wenn nicht in einer Schleife, denn Du hast da ja nicht 22 mal einen `append()`-Aufruf stehen.

Die SQL-Abfrage ergibt mehr als 22 Daten pro Datensatz? Wie das? Welche denn ausser den 22 Spaltennamen die in `properties` stehen denn noch?

Das mit dem `field` und `item` klang jetzt schon wieder geraten. Und wie man auf ``(zip(properties, data)[0])`` kommt, verstehe ich auch nicht, ausser wenn man nicht weisst was dieser Ausdruck bedeutet und was der Ausdruck ohne die Änderung von Dir bedeutet hat. Der Umgang mit Listen, Wörterbüchern, und Funktionen wie `zip()` ist wie schon gesagt *grundlegend*. So etwas braucht man in so ziemlich jedem Programm, darum solltest Du das echt erst einmal lernen. So ganz konkret mag Dir dabei niemand helfen weil es letztendlich darauf hinauslaufen würde Dir hier Texte von irgendwo anders abzutippen, denn die Grundlagen haben andere schon in Tutorials und Büchern aufgeschrieben. Unter anderem die Python-Entwickler selber in der Python-Dokumentation. Und das geht über "Hallo, Welt!" hinaus.

Alles was einem so über den Weg läuft was man nicht versteht, muss man dann nachlesen und sich erarbeiten, wenn man darüber stolpert. Du hättest Dir zum Beispiel zusätzlich zu den Grundlagen längst mal die `zip()`-Funktion und `dict()` anschauen müssen. Also die Dokumentation und dann mindestens in einer Python-Shell mal ein paar Beispiele ausprobieren müssen. Das sind Erfahrungen die Dir auch niemand anders abnehmen kann. Nur so lernt man mit diesen Werkzeugen umzugehen.
Antworten