Mediainfo ohne result

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.
Antworten
mys3lf
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 15:28

Hallo,

ich bin neu hier im Forum und auch neu in der Python Welt.
So langsam finde ich mich auch zurecht, aber dennoch brauche ich oftmals noch Hilfe.

Was habe ich vor?
Ich habe in einer Mysql DB eine Reihe von Pfaden, die ich gerne mit pymysql auslesen möchte.
Dies habe ich auch schon geschafft. Soweit so gut.

Nun möchte ich den ausgelesenen Pfad an die Mediainfodll übergeben, damit diese dann die Metadaten des Videos auslesen kann.
Nur leider bekomme ich jedes mal kein Ergebnis zurück.
Wenn ich den Pfad als variable im Quelltext mitgebe, funktioniert der Output.

Ich vermute, dass es sich um ein Zeichensatz-Problem handelt. Nur leider komme ich mit meinem Anfängerwissen hier nicht weiter.
Pythen benutze ich in der Version 2.7.9 unter Debian.

P.S.: Irgendwie finde ich meine SQL-Like-Abfrage unschön. Muss die so aussehen?

Code: Alles auswählen

# -*- coding: utf-8 -*-

from MediaInfoDLL import *
import pymysql.cursors
import pymysql





connection = pymysql.connect(host='localhost',
                             user='python_user',
                             password='python_user_pw',
                             db='test',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

try:

			with connection.cursor() as cursor:
			# Read a single record
				sql = "SELECT * FROM `test` WHERE `titel` like %s"
				cursor.execute(sql, ("%werner - volles%"))
				result = cursor.fetchall()
				
				if result:		
					for row in result:
						test1 = row["titel"]
						
						print(result)
						

					
			connection.commit()


finally:
			connection.close()

MI = MediaInfo()
print "Open"
MI.Open(test1)
print(test1)

print "My own metadata gettings!"
print MI.Get(Stream.Video, 0, u"Width")
print MI.Get(Stream.Video, 0, u"Height")
print MI.Get(Stream.General, 0, u"FileSize/String")
print MI.Get(Stream.General, 0, u"Duration/String")
print MI.Get(Stream.Video, 0, u"BitRate/String")
print MI.Get(Stream.Video, 0, u"FrameRate/String")
print MI.Get(Stream.Audio, 0, u"Language/String")
print MI.Get(Stream.Audio, 0, u"Language")
print MI.Get(Stream.Audio, 0, u"Title")
print MI.Get(Stream.Audio, 0, u"BitRate/String")
Zuletzt geändert von Anonymous am Donnerstag 13. Juli 2017, 16:24, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@mys3lf: Ist in der Spalte `titel` in der Datenbank denn ein Dateiname hinterlegt der absolut ist, und falls nicht der relativ zum Arbeitsverzeichnis des Programms ist?

Der `execute()`-Aufruf dürfte so nicht funktionieren, denn die Abfrage enthält nur einen Platzhalter, Du übergibst aber 17 Werte: '%', 'w', 'e', 'r', 'n', 'e', 'r', ' ', '-', ' ', 'v', 'o', 'l', 'l', 'e', 's', und '%'. Das zweite Argument muss eine Sequenz von Werten sein. Und eine Zeichenkette ist eine Sequenz von Werten — nämlich den einzelnen Buchstaben.

Der Kommentar ``# Read a single record`` ist falsch, oder würde nur eher zufällig stimmen. Effektiv liest Du alle und merkst Dir nur den letzten. Um *einen* Datensatz zu lesen verwendet man nicht `fetchall()`.

Das ``if result:`` ist überflüssig. Du hast ohne die Zeile exakt das gleiche Laufzeitverhalten des Programms. Und in beiden Fällen ein Problem mit einem undefinierten `test1` wenn kein Datensatz zutrifft.

Namen komplett in Grossbuchstaben stehen konventionell für Konstanten. Und man sollte keine Abkürzungen verwenden. Also `media_info` oder `info` statt `MI`.

Sternchen-Importe führen schnell zu Code bei dem man nicht mehr so einfach sieht woher welcher Name kommt. Ausserdem besteht die Gefahr von Namenskollisionen.
mys3lf
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 15:28

Hallo BlackJack,

danke für die schnelle Antowrt.

Ja es befindet sich in der Spalte ein Titel/Pfad ->/test/Werner - Volles Rooäää!!!.mkv

Wie müsste so eine sql abfrage denn aussehen ?
Ich habe diese schlicht aus einem Tutorial übernommen und war froh das sie funktioniert.

Der Kommentar stammt ebenfalls noch aus dem Tutorial. Ebenso habe ich das 'fetchall()' selber geändert. Im Tutorial hieß es auch 'fetchone()'

Das 'if result' werde ich dann weg lassen. Und den Namen 'MI' werde ich auch ändern.

Code: Alles auswählen

# -*- coding: utf-8 -*-

from MediaInfoDLL import *
import pymysql.cursors
import pymysql


teststring="Werner - Volles"


connection = pymysql.connect(host='localhost',
                             user='python_user',
                             password='python_user_pw',
                             db='test',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

try:

			with connection.cursor() as cursor:
			# Read a single record
				sql = "SELECT `titel` FROM `test` WHERE `titel` like '%" + teststring + "%'"
				cursor.execute(sql)
				result = cursor.fetchall()
				
				for row in result:
					print(result)
					test1 = row['titel']
									
			connection.commit()


finally:
			connection.close()

media = MediaInfo()
print "Open"
media.Open(test1)
print(test1)

print "My own metadata gettings!"
print media.Get(Stream.Video, 0, u"Width")
print media.Get(Stream.Video, 0, u"Height")
print media.Get(Stream.General, 0, u"FileSize/String")
print media.Get(Stream.General, 0, u"Duration/String")
print media.Get(Stream.Video, 0, u"BitRate/String")
print media.Get(Stream.Video, 0, u"FrameRate/String")
print media.Get(Stream.Audio, 0, u"Language/String")
print media.Get(Stream.Audio, 0, u"Language")
print media.Get(Stream.Audio, 0, u"Title")
print media.Get(Stream.Audio, 0, u"BitRate/String")
Zuletzt geändert von Anonymous am Donnerstag 13. Juli 2017, 17:22, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@mys3lf: nein, man formatiert keine Werte in SQL-Statements! Dein erster Versuch war fast richtig, nur mußt Du als zweites Argument an »execute« ein Tuple übergeben.

Code: Alles auswählen

cursor.execute(sql, ("%werner - volles%",))
Ein commit macht bei einem SELECT keinen Sinn.
BlackJack

@mys3lf: Und es gibt tatsächlich den *absoluten* Pfad '/test/Werner - Volles Rooäää!!!.mkv' auf dem Rechner? Und bei Windows spielt das aktuelle Laufwerk wahrscheinlich noch eine Rolle.

Wenn Du Dir die Dateiinformationen mit der MediaInfo-GUI anschaust, dann wird alles angezeigt?

SQL als Zeichenkette zusammenbasteln und da Werte hinein zu formatieren kann im besten Fall unperformant sein und im schlechtesten Fall eine Sicherheitslücke! Das sollte man immer das Datenbankmodul erledigen lassen.

Du musst den *einen* Wert in einer Sequenz mit eben diesem einen Wert als einzigem Element übergeben. Zum Beispiel in einer Liste. (Das ist syntaktisch etwas leichter zu erkennen als ein Tupel mit einem Element.)

Warum hast Du denn aus dem `fetchone()` ein `fetchall()` gemacht wenn Du am Ende doch nur *einen* Datensatz tatsächlich verwendest? Zudem noch einen zufälligen, denn die Reihenfolge ist ohne eine ORDER BY-Klausel nicht garantiert.

@Sirius3: `commit()` kann auch nach einem SELECT Sinn machen. Kommt auf's Isolationslevel an und was man sonst noch so macht. Hier ist es natürlich sinnlos weil die Verbindung geschlossen wird.
mys3lf
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 15:28

Hallo,

Die SQL-Query werde ich wieder ändern.
Ich habe aus dem 'fetchone' ein 'fetchall' gemacht, da ich sonst immer fehler bei der Abfrage erhalte. Sobald ich wieder zu Hause bin kann ich auch gerne ein Beispiel anhängen.

Der Pfad ist in sofern absolut, dass das Laufwerk auf dem die Datei liegt unter Debian gemountet ist.
Wenn ich der Mediainfo den Pfad als Variable übergebe:

Code: Alles auswählen

media = MediaInfo()
print "Open"
pfad="/test/Werner - Volles Rooäää!!!.mkv"
media.Open(pfad)
print(pfad)
 
print "My own metadata gettings!"
print media.Get(Stream.Video, 0, u"Width")
print media.Get(Stream.Video, 0, u"Height")
print media.Get(Stream.General, 0, u"FileSize/String")
print media.Get(Stream.General, 0, u"Duration/String")
print media.Get(Stream.Video, 0, u"BitRate/String")
print media.Get(Stream.Video, 0, u"FrameRate/String")
print media.Get(Stream.Audio, 0, u"Language/String")
print media.Get(Stream.Audio, 0, u"Language")
print media.Get(Stream.Audio, 0, u"Title")
print media.Get(Stream.Audio, 0, u"BitRate/String")
bekomme ich leider keinen Output, da irgend etwas mit dem Zeichensatz nicht stimmt. (vermutlich wegen "äää")
Wenn ich allerdings einen Pfad ohne die Sonderzeichen (äöü) angeben bekomme ich den erwarteten output. Auch wenn dieser Pfad via SQL ermittelt wird.
Daher habe ich ja im ersten Post bereits geschrieben, das ich vermute, dass es mit den Sonderzeichen/Zeichensatz zusammen hängt.
Zuletzt geändert von Anonymous am Freitag 14. Juli 2017, 08:39, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@mys3lf: Laut Issue #144 muss man unter Linux die „locale“ richtig setzen damit Zeichen ausserhalb von ASCII richtig funktionieren. Also mindestens LC_CTYPE:

Code: Alles auswählen

import locale
locale.setlocale(locale.LC_CTYPE, locale.getdefaultlocale())
Edit: Die `Open()`-Methode sollte übrigens einen Wert zurückgeben den man als Wahrheitswert interpretieren kann und der angibt ob die Datei geöffnet werden konnte oder nicht.
mys3lf
User
Beiträge: 5
Registriert: Donnerstag 13. Juli 2017, 15:28

Hallo,

ich habe jetzt mal ein paar der Änderungen umgesetzt.
Das eigentliche Problem ist hierdurch nun auch gelöst.

Es bleibt nur noch das Problem mit der 'fetchone()' deklaration.

Aber hier erst einmal der Code:

Code: Alles auswählen

# -*- coding: utf-8 -*-

from MediaInfoDLL import *
import pymysql.cursors
import pymysql
import locale
locale.setlocale(locale.LC_CTYPE, locale.getdefaultlocale())

teststring="werner - volles"


connection = pymysql.connect(host='localhost',
                             user='python_user',
                             password='python_user_pw',
                             db='test',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

try:

			with connection.cursor() as cursor:
			# Read a single record
				sql = "SELECT `titel` FROM `test` WHERE `titel` like %s"
				cursor.execute(sql,("%" + teststring +"%",))
				result = cursor.fetchone()
				
				for row in result:
					print(result)
					test1 = row['titel']
														
			connection.commit()


finally:
			connection.close()

media = MediaInfo()
print "Open"
media.Open(test1)
print(test1)

print "My own metadata gettings!"
print media.Get(Stream.Video, 0, u"Width") #breite
print media.Get(Stream.Video, 0, u"Height")
print media.Get(Stream.General, 0, u"FileSize/String")
print media.Get(Stream.General, 0, u"Duration/String")
print media.Get(Stream.Video, 0, u"BitRate/String")
print media.Get(Stream.Video, 0, u"FrameRate/String")
print media.Get(Stream.Audio, 0, u"Language/String")
print media.Get(Stream.Audio, 0, u"Language")
print media.Get(Stream.Audio, 0, u"Title")
print media.Get(Stream.Audio, 0, u"BitRate/String")

Wenn ich den Code so ausführe erhalte ich folgenden Fehler:

Code: Alles auswählen

Traceback (most recent call last):
  File "mediainfo_test.py", line 31, in <module>
    test1 = row['titel']
TypeError: string indices must be integers
Warum benötigt er hier ein Integer? Wenn ich '0' statt 'titel' eingebe, ist der Fehler weg, allerdings bekomme ich als test1 ->"t".
Das kommplette 'result' beinhaltet: [{u'titel': u'/test/Werner - Volles Rooäää!!!.mkv''}]

Habt ihr hierfür noch eine Idee ?
Zuletzt geändert von Anonymous am Freitag 14. Juli 2017, 15:43, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
BlackJack

@mys3lf: `row` ist in diesem Fall nicht das was Du denkst, denn `result` hat *nicht* den Wert ``[{u'titel': u'/test/Werner - Volles Rooäää!!!.mkv''}]``. Das war das Ergebnis von `fetchall()`, das eine Liste mit den Ergebnissen liefert. Es macht keinen Sinn eine Liste mit Ergebnissen von `fetchone()` zu erwarten, denn die hätte ja grundsätzlich nur ein Element.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

Und ohne Schleide nur mit print(result[0]) usw., wie sieht Dein Ergebnis dann aus?
Wobei ich gerade nicht diese Ausgabe nachvollziehen kann, ich erhalte einen ganz normalen Tupel.
BlackJack

@Melewo: Hast Du beim `connect()` auch das `cursorclass`-Argument so angegeben?
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

@ BlackJack: Na ja, sieht ein kleinwenig anders aus als bei mir, doch ausgegeben bekommt man es ja eigentlich immer. Ob so oder so, so lange result nicht leer bleibt, lässt es sich halt verwerten.

Code: Alles auswählen

result = [{u'titel': u'/test/Werner - Volles Rooäää!!!.mkv'}]
print(result[0]['titel'])
# /test/Werner - Volles Rooäää!!!.mkv

result = (u'titel', u'/test/Werner - Volles Rooäää!!!.mkv')
print(result[1])
# /test/Werner - Volles Rooäää!!!.mkv
BlackJack

@Melewo: Was soll denn dieses Beispiel jetzt? Das bringt doch noch mehr Verwirrung als das es irgendwas klärt. Das erste kann kein Ergebnis von `fetchone()` sein, und das zweite kann gar kein Ergebnis von irgendwas sein, denn wo soll denn das erste Element aus dem Tupel her kommen? Da müsste das SELECT schon so ausgesehen haben: ``SELECT 'title', title FROM test WHERE title LIKE '%werner - volles%'``.
Melewo
User
Beiträge: 320
Registriert: Mittwoch 3. Mai 2017, 16:30

mys3lf hat geschrieben:Das kommplette 'result' beinhaltet: [{u'titel': u'/test/Werner - Volles Rooäää!!!.mkv''}]

Habt ihr hierfür noch eine Idee ?
War meine Antwort darauf, denn das war sein result von result = cursor.fetchone(), zumindest schrieb es mys3lf so.
BlackJack

@Melewo: Da ist es aber nicht weil `fetchone()` keine Liste liefert. So sieht das Ergebnis von `fetchall()` aus. Beide Deine `result`-Beispiele haben nichts mit dem Problem zu tun, denn so sieht das `result` von mys3lf nicht aus.
Antworten