2013-01-09 9 views
15

Ich habe ein Problem beim Einfügen von Unicode in ein Oracle-Schema, ich denke, die Datenbank ist eine Oracle 11g-Instanz, aber bin mir nicht sicher, an dieser Stelle. Ich benutze Python 2.6.1 unter OS X 10.6.8 (dies ist die Systemversion von Python) und verwende das cx-Oracle-Treibermodul, Version 5.1, das von sourceforge.net heruntergeladen, auf eine virtualenv 1.6.1-Instanz gebaut und installiert wurde mit Website-Paketen sichtbar. Mein Skript ist wie folgtKann Unicode nicht mit cx-Oracle einfügen

import cx_Oracle 

    connection = cx_Oracle.connect(
     "<name>/<password>@<host>/<service-name>" 
    ) 
    cursor = connection.cursor() 
    result = cursor.execute(u"create table UNICODE_TEST (id NUMBER(6), text NCLOB not NULL)") 

    raw_text = open("test.txt",'r').read() 
    if isinstance(raw_text,str): 
     raw_text = raw_text.decode("utf_8") 

    statement = u"insert into UNICODE_TEST (id, text) values (1,'%s')" % raw_text 
    result = cursor.execute(statement) 

ich eine Verbindung erstellen, um den Cursor zu erstellen, führen Sie einen statment eine Testtabelle mit einer ID und Textfeld der Typen NUMBER und NCLOB zu erstellen. Ich öffne eine Datei mit dem, was ich weiß, um in UTF-8 codiert zu sein, dekodiere die Zeichenfolge zu Unicode. Erstellen Sie eine Einfügungstatement in einer Unicode-Zeichenfolge und führen Sie diese Anweisung aus, und das Ergebnis ist dieser Fehler.

Etwas versucht, meine Anweisung als ASCII zu kodieren, bevor sie in das Oracle-Schema eingefügt wird. Also begann ich die Jagd umsah, um besser zu verstehen, wie cx-Oracle Unicode behandelt und fand diese in der HISTORY.txt der cx-Oracle-Quelle I von sourceforge.net heruntergeladen

Änderungen von 5.0.4 auf 5.1
1) Entfernen Sie die Unterstützung für UNICODE-Modus und Erlaube Unicode in überall wo eine Zeichenfolge übergeben werden kann. Dies bedeutet, dass Zeichenfolgen an Oracle über den Wert der NLS_LANG Umgebung Variable in Python 3.x übergeben werden auch. Dadurch wurde eine Reihe von Problemen behoben, die mit dem UNICODE-Modus entdeckt wurden. Außerdem wurde eine unnötige Einschränkung in Python 2.x entfernt, die Unicode beispielsweise in Verbindungszeichenfolgen oder SQL-Anweisungen nicht verwenden konnte. ...

Meine Vermutung ist, dass die Umgebungsvariable NLS_LANG zu ‚ascii‘ oder einem Äquivalent gesetzt ist, also versuche ich NLS_LANG auf ‚AL32UTF8‘, die ich glaube, der richtige Wert für Unicode ist, und stellen Sie die neuer Wert vor dem Erstellen meiner Verbindung.

os.environ["NLS_LANG"] = "AL32UTF8" 
    connection = cx_Oracle.connect(
     "<user>/<password>@<host>/<service-name>" 
    ) 
    cursor = connection.cursor() 
    ... 

Aber ich bekomme diesen Fehler.

Traceback (most recent call last): 
    File "unicode-test.py", line 11, in <module> 
     "<user>/<password>@<host>/<service-name>" 
    cx_Oracle.DatabaseError: ORA-12705: Cannot access NLS data files or invalid environment specified 

Es sieht also so aus, als ob ich den NLS_LANG-Wert nicht manipulieren kann.

Hier sind meine Fragen ab sofort. Fehle ich etwas Einfaches wie ein falscher Säulentyp? Ist das Problem mit dem cx-Oracle-Treiber? Muss ich beim Erstellen des cx-Oracle-Moduls die Umgebungsvariable "WITH_UNICODE" setzen und wie würde ich das machen? Ist das Problem mit der Oracle-Instanz? Ich habe wenig Erfahrung mit Oracle und habe nie mit Oracle und Python zusammen gearbeitet. Ich habe zwei Tage an diesem Thema gearbeitet und möchte das Problem besser verstehen, bevor ich in die DBA-Gruppe gehe.

Danke,

Antwort

14

Umgebungsvariable ist der richtige Weg, aber „AL32UTF8“ ist nicht der richtige Wert für NLS_LANG. Um den richtigen Wert des in Ihrer Instanz von Oracle verwendeten NLS_LANG zu erhalten, führen Sie

SELECT USERENV ('language') FROM DUAL 
+0

Dank für die Antwort erhielt ich endlich eine Antwort von meinem DBAs.Für unsere 11gR2 Installation ist das CHARACTER SET 'WE8MSWIN1252' und das NATIONAL CHARACTER SET 'AL16UTF16'. Es scheint, dass der Treiber die Codierung, die in den obigen Variablen festgelegt wird, nicht korrekt erkennt. Das Überprüfen der 'encoding' und 'nencoding' Attribute auf der Verbindung ergibt in beiden Fällen 'US-ASCII', was inkorrekt ist. Ich bekomme immer noch den gleichen DatabaseError, wenn ich NLS_LANG zu 'AL16UTF16' versuche, was seit meiner Verbindung mit dem Schema remove (und wird auch in Produktion sein) erklärt, warum auf diese Dateien nicht zugegriffen werden kann. – snarkyname77

+0

In meiner Situation, mein Ergebnis von der obigen Abfrage ist "AMERICAN_AMERICA.US7ASCII". Meine Unicode-Einfügungen begannen jedoch korrekt zu funktionieren, sobald mein NLS_LANG auf "_.AL32UTF8" (ohne Anführungszeichen) gesetzt wurde. – davidjb

+0

Mein Ergebnis aus der obigen Abfrage ist AMERICAN_AMERICA.WE8MSWIN1252. @davidjb, wie legen Sie es auf diesen Wert ohne Anführungszeichen fest. Was hast du in deinen Umfang importiert, um es zu bekommen? – ThatAintWorking

Verwandte Themen