Seltsames Verhalten von SQLite

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Hallo

ich speichere 8-Zeichen-MD5-Hashes in zwei Tabellen (Text-Felder) und wenn ich mir danach mit nem Database Browser die DB anschaue, finde ich unter plötzlich im betreffenden Feld unter vielen normalen Werte auch Werte wie "50597000000000", "325086000000000" oder "NaN".

Es hat definitiv etwas mit der DB zu, in Python stimmen die Werte.

Code: Alles auswählen

con = sqlite3.connect(db)
cur = con.cursor()

for book in books:
    cur.execute("insert into books(md5_hash, isbn) values \
                   (?, ?)", (book.hash, book.isbn))
    cur.execute("insert into stats(md5_hash, date_entered) values \
                   (?, ?)", (book.hash, today))
con.commit()
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

Was wird ausgegeben wenn du print repr(book.hash) in der Schleife machst?

Gruss
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

alan hat geschrieben:ich speichere 8-Zeichen-MD5-Hashes in zwei Tabellen (Text-Felder) und wenn ich mir danach mit nem Database Browser die DB anschaue, finde ich unter plötzlich im betreffenden Feld unter vielen normalen Werte auch Werte wie "50597000000000", "325086000000000" oder "NaN".
Hallo alan!

TEXT-Felder --> TEXT-Daten (UTF-8-codiert oder Unicode).

Kümmere dich darum, dass diese "Hash"-Werte (wie auch immer du es schaffst an diese 8-Byte-Werte zu kommen) auch wirklich Text (UTF-8-codiert) oder Unicode sind, bevor du sie in die SQLite-Datenbank schreibst. Dann sollte alles normal laufen.

http://www.python-forum.de/topic-6654.html

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Sag mal gerold, hast du wirklich zu allem, was mir so an Problemen begegnet, schon ein Tutorial geschrieben? :D
(Ist irgendwo eine Liste?)

@rayo
Allesamt nur korrekte Werte.

Edit:
Kann man sich zu Debugging-Zwecken von einem String das Encoding ausgeben lassen?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

alan hat geschrieben:Kann man sich zu Debugging-Zwecken von einem String das Encoding ausgeben lassen?
Nein. Bei einem Bytestring ist ja nicht bekannt, in welchem Encoding er ist. Sonst wäre ja alles ganz einfach.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Ich weiß worans lag...

Die Daten sind schon richtig in der DB, nur der sqlitebrowser hat nen Bug und zeigt sie nicht richtig an.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

alan hat geschrieben:Die Daten sind schon richtig in der DB, nur der sqlitebrowser hat nen Bug und zeigt sie nicht richtig an.
Hallo alan!

Ich kann mir kaum vorstellen, dass der SQLite-Browser nicht mit reinem ASCII klar kommt. Und wenn es kein TEXT ist, dann ist es als Primärschlüssel sowiso ungeeignet. Außerdem würde ich niemals nur 8 Byte vom MD5-(Hex)digest nehmen. Die Gefahr, dass es doch einen doppelten Schlüssel gibt, wäre mir einfach zu hoch. Nimm doch den kompletten MD5-Hexdigest. Dann hast du einen schönen String, der sich leicht indizieren lässt und kein Binär-Irgendetwas.

Code: Alles auswählen

>>> import md5
>>> m = md5.new()
>>> m.update("asdf")
>>> m.update("ddd")
>>> m.digest()
'\xe7\xedv`\xbf\xdc\xa2,W[\x18\xa1\xe2\x88\xf5\xaa'
>>> print m.digest() # wie man sieht ist das irgend ein Binärzeugs
çív`¿Ü¢,W[¡âˆõª
>>> m.hexdigest() # = schöner String
'e7ed7660bfdca22c575b18a1e288f5aa'
>>> 
Aber vielleicht ist das alles gar nicht nötig und du kannst mit Ganzzahlen (INTEGER PRIMARY KEY) als Primärschlüssel arbeiten.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

gerold hat geschrieben:Außerdem würde ich niemals nur 8 Byte vom MD5-(Hex)digest nehmen. Die Gefahr, dass es doch einen doppelten Schlüssel gibt, wäre mir einfach zu hoch. Nimm doch den kompletten MD5-Hexdigest. Dann hast du einen schönen String, der sich leicht indizieren lässt und kein Binär-Irgendetwas.
Das kam mir ziemlich unwahrscheinlich vor..aber du hast Recht.

Taugt das hier mehr?

Code: Alles auswählen

def newHash():
    return md5.new(time.ctime() + str(random.randint(0, 10**9))).hexdigest()
BlackJack

Ähm, das ist kein Hash sondern irgendein Zufallswert würde ich mal sagen. Ein Hashwert gehört zu einem Objekt und eine Hashfunktion gibt für das gleiche Objekt immer den gleichen Hashwert zurück.

Was Du da mit der Funktion machst geht einfacher ohne MD5:

Code: Alles auswählen

In [5]: os.urandom(16).encode('hex')
Out[5]: 'aaa4aed561a983ebbae1a4b3934a9073'
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

Schön und gut, aber besteht nicht bei einem reinem Zufallswert eben die (geringe) Gefahrt, dass er irgendwann nicht mehr einzigartig ist?

Wenn man mal von Kollisionen absieht, leistet MD5 doch genau das.

Das ist aber alles ziemlich hypothetisch...:D
BlackJack

Die Gefahr besteht, daran ändert aber `md5` auf Zufallszahlen angewendet nichts.

Wenn Du die Zeit, möglichst genau, plus einer Zufallszahl direkt nimmst sind die Chancen einer Kollision geringer als wenn Du das noch einmal durch `md5` jagst.

Beispiel: Mal angenommen die Zeit alleine wäre so hochaufgelöst, das es nie Kollisionen gäbe. Das wäre perfekt. Wenn Du jetzt auf diese perfekten Zeiten `md5` anwendest, besteht eine geringe Chance das zwei Zeiten den selben Hashwert ergeben. Also hast Du die Situation mit `md5` *verschlechtert*.
alan
User
Beiträge: 81
Registriert: Dienstag 10. April 2007, 11:30

BlackJack hat geschrieben: Beispiel: Mal angenommen die Zeit alleine wäre so hochaufgelöst, das es nie Kollisionen gäbe. Das wäre perfekt. Wenn Du jetzt auf diese perfekten Zeiten `md5` anwendest, besteht eine geringe Chance das zwei Zeiten den selben Hashwert ergeben. Also hast Du die Situation mit `md5` *verschlechtert*.
Ok seh ich ein :wink:
Antworten