PyGreSQL und Sonderzeichen

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
ullat
User
Beiträge: 3
Registriert: Mittwoch 18. Juli 2007, 14:14

PyGreSQL und Sonderzeichen

Beitragvon ullat » Donnerstag 13. September 2007, 13:50

Hallo Forum,

wie kann man Sonderzeichen, wie z.B. Umlaute per Python und PyGreSQL in die PostgreSQL Datenbank bekommen?

Ich habe folgendes Verhalten:

[code=]>>> conn.query("SELECT * FROM A1339 WHERE NAME = 'Schweiz'")
<pg query result>
>>> conn.query("SELECT * FROM A1339 WHERE NAME = 'Österreich'")

Traceback (most recent call last):
File "<pyshell#32>", line 1, in -toplevel-
conn.query("SELECT * FROM A1339 WHERE NAME = 'Österreich'")
ProgrammingError: ERROR: invalid byte sequence for encoding "UNICODE": 0xd673[/code]

Der Versuch vorab den String in Unicode umzuwandeln misslang, da die query-Funktion einen String und kein Unicode erwartet.

[code=]unicode("Österreich", "latin-1") [/code]

Ich bin für jede Hilfe sehr dankbar!

Viele Grüße,
Ulla.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 13. September 2007, 15:55

Was ist wenn du den String UTF-8 kodierst? PostgreSQL wirft AFAIR UNICODE und UTF8 etwas durcheinander.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Re: PyGreSQL und Sonderzeichen

Beitragvon gerold » Donnerstag 13. September 2007, 16:03

ullat hat geschrieben:wie kann man Sonderzeichen, wie z.B. Umlaute per Python und PyGreSQL in die PostgreSQL Datenbank bekommen?

Hallo Ulla!

Willkommen im Python-Forum!

Ich kenne PyGreSQL nur vom Hören und Sagen. Ich setze *psycopg2* ein. Ich kann mir aber denken, dass PyGreSQL das mit den Umlauten ähnlich wie *psycopg2* macht.

Du darfst die Felder mit den Umlauten nicht direkt in die SQL-Anweisung schreiben. Lass die Datenbankschnittstelle die Arbeit machen. Kümmere dich einfach darum, dass die Daten in Unicode vorliegen.

Code: Alles auswählen

# -*- coding: iso-8859-15 -*-

namen = (
  [u"Ülrich"],
  [u"Österreicher"]
)
sql = "INSERT INTO tabellenname (name) VALUES (?)"
for name in namen:
    connection.execute(sql, name)
connection.commit()

Vielleicht musst du bei PyGreSQL statt dem "?" einen anderen Platzhalter verwenden.

Umgelegt auf dein Beispiel:

Code: Alles auswählen

sql = "SELECT * FROM A1339 WHERE NAME = ?"
cursor.execute(sql, u"Österreich")
...

mfg
Gerold
:-)

PS: ...und wenn du statt "conn.query" nicht "conn.execute" einsetzen kannst, dann würde ich so schnell wie möglich auf *psycopg2* umsteigen. Je früher, desto besser.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
ullat
User
Beiträge: 3
Registriert: Mittwoch 18. Juli 2007, 14:14

Danke, jetzt funktioniert es!

Beitragvon ullat » Samstag 15. September 2007, 14:57

Hallo zusammen,

die Tipps haben mir sehr gehofen. :)

Ebenfalls sehr hilfreich war der folgende Beitrag zu String, Unicode und UTF-8, den ich jedem der ein Umlaut-Problem hat nur weiterempfehlen kann:

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

Bevor ich ein SQL-Statement an PyGreSQL übergebe mache ich jetzt folgende Umwandlungsschritte:

[code=] statement = statement.decode("latin-1")
statement = statement.encode("utf-8")[/code]

Vielleicht geht es auch in einem Schritt. Aber auf jeden Fall funktioniert es in diesen beiden ....

Vielen Dank!
Ulla.
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Beitragvon Byte » Samstag 20. Oktober 2007, 20:21

Hi Gerold,

habe das gleiche Problem mit psycopg2, habe aber bisher auch immer die Werte mit den Stringfunktionen von Pyhton eingefügt. Ist das mit dem "?" irgenwo dokumentiert? Funktioniert das auch mit mehreren Werten.

:? Gruß Christian
BlackJack

Beitragvon BlackJack » Samstag 20. Oktober 2007, 20:51

Das mit dem '?' ist SQL-Standard und auch in PEP 249 - Python Database API Specification v2.0 beschrieben. Die DB API 2.0 wird von allen ernstzunehmenden Datenbankmodulen implementiert.
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Beitragvon Byte » Sonntag 21. Oktober 2007, 16:32

Hallo,

irgendwie bin ich nicht fähig, das hinzukriegen. Es folgt mein Testcode.

Code: Alles auswählen

[quote]connection = pg.connect(dsn)
cursor = connection.cursor()
sql = "SELECT * FROM name WHERE name = ?"
cursor.execute(sql, u"Name")
connection.commit()


In der Logdatei von Postgre sehe ich folgende Fehlermeldung, irgendwie geht das mit dem "?" als Platzhalter nicht, er wird nicht ersetzt.

2007-10-21 17:17:30 STATEMENT: SELECT * FROM name WHERE name = ?
2007-10-21 17:19:01 ERROR: syntax error at end of input at character 34


Habe auch schon probiert, das Leerzeichen vor dem ? und dem = zu entfernen, aber dann meckert er weil er das als Operator ansieht.

2007-10-21 17:15:31 ERROR: operator does not exist: character varying =? at character 30
2007-10-21 17:15:31 HINT: No operator matches the given name and argument type(s). You may need to add explicit type casts.
2007-10-21 17:15:31 STATEMENT: SELECT * FROM name WHERE name=?


Woran könnte das liegen? Irgendwie habe ich da eine Blockade.

Gruß Christian
BlackJack

Beitragvon BlackJack » Sonntag 21. Oktober 2007, 17:33

Hm, da hätte eigentlich `cursor.execute()` schon meckern müssen. Das zweite Argument sollte eine Sequenz mit Argumenten sein und keine Unicode-Zeichenkette.
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Beitragvon Byte » Sonntag 21. Oktober 2007, 17:58

Ich habe eigentlich nur den Code aus Gerolds Posting genommen, weil es bei meiner Anwendung nicht funktioniert hat. Aber auch das geht nicht.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Sonntag 21. Oktober 2007, 18:41

Hallo Byte!

Zeige uns doch bitte mal, ein bei dir nicht funktionierendes Codebeispiel. Aber bitte komplett. Nicht nur einen Auschnitt davon.

Dann brauchen wir noch das komplette Traceback. Also die komplette Fehlermeldung die Python ausspuckt.

Dann können wir dir wahrscheinlich sofort sagen, woran es liegt.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Beitragvon Byte » Sonntag 21. Oktober 2007, 19:42

Hallo,

Mein Code:

Code: Alles auswählen

#!/bin/env python
# -*- coding: iso-8859-15 -*-

import psycopg2 as pg

wert = u"Zeile1"

connection = pg.connect("host=localhost dbname=test user=test password=test")
cursor = connection.cursor()
sql = "SELECT * FROM t_tabelle WHERE spalte1 = ?"
cursor.execute(sql, wert)
connection.commit()
print cursor.fetchall()


Erzeugt folgendes:

Traceback (most recent call last):
File "D:\Programmierung\Faktura\Programm\test.py", line 11, in
cursor.execute(sql, wert)
psycopg2.ProgrammingError: syntax error at end of input
LINE 1: SELECT * FROM t_tabelle WHERE spalte1 = ?
^
Script terminated.



Zeile 10 und 11 ersetzt mit:

Code: Alles auswählen

sql = "SELECT * FROM t_tabelle WHERE spalte1 = 'Zeile1'"
cursor.execute(sql)


ergibt:

[('Zeile1',)]
Script terminated.



Danke für die Hilfe und Gruß

:?: Christian
BlackJack

Beitragvon BlackJack » Sonntag 21. Oktober 2007, 20:04

Wie gesagt, das zweite Argument von `execute()` muss eine Sequenz, also zum Beispiel ein Tupel von Werten sein und nicht ein einzelner Wert.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Montag 22. Oktober 2007, 09:20

Mein Fehler!

Du musst bei psycopg2 als Platzhalter verwenden.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Montag 22. Oktober 2007, 10:56

Hallo!

Ich habe alles mal in ein kleines Beispiel zusammengefasst. Vielleicht kann einer von euch damit etwas anfangen:

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

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Beitragvon Byte » Montag 22. Oktober 2007, 19:30

Hallo,

danke Black Jack und Gerold für eure Hilfe. Ich habe mal mein kleines Beispiel mit einem Insert so umgebaut dass es bei mir funktioniert.

Code: Alles auswählen

#!/bin/env python
# -*- coding: iso-8859-15 -*-

import psycopg2 as pg

wert = (u"ÄÖÜß", u"Wert 2")

# Zum einfügen eines einzelnen Wert muss es auch ein Tupel sein
# wert = (u"Wert 1",)

connection = pg.connect("host=localhost dbname=test user=test password=test")
cursor = connection.cursor()
sql = "INSERT INTO t_tabelle values (%s, %s)"
cursor.execute(sql, wert)
connection.commit()



:D Christian

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder