Seite 1 von 1

Mediainfo ohne result

Verfasst: Donnerstag 13. Juli 2017, 15:40
von mys3lf
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")

Re: Mediainfo ohne result

Verfasst: Donnerstag 13. Juli 2017, 16:39
von 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.

Re: Mediainfo ohne result

Verfasst: Donnerstag 13. Juli 2017, 16:46
von mys3lf
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")

Re: Mediainfo ohne result

Verfasst: Donnerstag 13. Juli 2017, 17:36
von Sirius3
@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.

Re: Mediainfo ohne result

Verfasst: Donnerstag 13. Juli 2017, 18:09
von 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.

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 06:49
von mys3lf
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.

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 08:49
von 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.

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 14:16
von mys3lf
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 ?

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 15:46
von 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.

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 15:53
von Melewo
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.

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 16:31
von BlackJack
@Melewo: Hast Du beim `connect()` auch das `cursorclass`-Argument so angegeben?

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 18:21
von Melewo
@ 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

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 19:13
von 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%'``.

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 20:08
von Melewo
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.

Re: Mediainfo ohne result

Verfasst: Freitag 14. Juli 2017, 20:36
von 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.