Sto riscontrando un problema nell'inserimento di unicode in uno schema Oracle, penso che il database sia un'istanza di Oracle 11g ma non sono sicuro a questo punto. Sto usando python 2.6.1 su OS X 10.6.8 (questa è la versione di sistema di python) e sto usando il modulo del driver cx-Oracle versione 5.1 scaricato da sourceforge.net, compilato e installato su un'istanza virtualenv 1.6.1 con i pacchetti del sito visibili. Il mio script è il seguenteImpossibile inserire Unicode utilizzando cx-Oracle
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)
creo una connessione, creare il cursore, eseguire uno statment per creare una tabella di test con un campo id e il testo dei tipi di numero e NCLOB. Apro un file contenente quello che so essere codificato in formato testo in UTF-8, decodificare la stringa in unicode. Creare una dichiarazione di inserimento in una stringa unicode ed eseguire tale istruzione e il risultato è questo errore.
Traceback (most recent call last):
File "unicode-test.py", line 19, in <module>
result = cursor.execute(statement)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2122' in position 170: ordinal not in range(128)
Qualcosa sta cercando di codificare la mia dichiarazione come ASCII prima di inserirlo nello schema Oracle. Così ho iniziato a caccia in giro a cercare di capire meglio come cx-Oracle gestisce unicode e trovato questo nel HISTORY.txt della sorgente cx-Oracle ho scaricato da sourceforge.net
modifiche da 5.0.4 a 5.1
1) Rimuovere il supporto per la modalità UNICODE e consentire il passaggio di Unicode in ovunque venga inoltrata una stringa. Ciò significa che le stringhe saranno passate da a Oracle utilizzando il valore della variabile ambiente in Python 3.x anche. In questo modo sono stati eliminati alcuni problemi rilevati utilizzando la modalità UNICODE e rimosso anche una limitazione non necessaria in Python 2.x che non è possibile utilizzare Unicode nelle stringhe di connessione o istruzioni SQL, ad esempio. ...
La mia ipotesi è che la variabile d'ambiente NLS_LANG è impostato su 'ascii' o qualche equivalente, in modo da provare a impostare NLS_LANG a 'AL32UTF8' che credo sia il valore corretto per unicode, e impostare il nuovo valore prima di creare la mia connessione.
os.environ["NLS_LANG"] = "AL32UTF8"
connection = cx_Oracle.connect(
"<user>/<password>@<host>/<service-name>"
)
cursor = connection.cursor()
...
Ma ho ricevuto questo errore.
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
Quindi sembra che non sia possibile manomettere il valore NLS_LANG.
Ecco le mie domande fin d'ora. Mi manca qualcosa di semplice come un tipo di colonna errato? Il problema con il driver cx-Oracle è? Devo impostare la variabile di ambiente "WITH_UNICODE" quando creo il modulo cx-Oracle e come dovrei farlo? Il problema è con l'istanza di Oracle? Ho poca esperienza con Oracle e non ho mai lavorato con Oracle e Python insieme. Ho trascorso due giorni a lavorare su questo problema e vorrei una migliore comprensione di quale sia il problema prima di andare al gruppo DBA con.
Grazie,
Grazie per la risposta, ho finalmente ricevuto una risposta dai miei DBA.Per la nostra installazione 11gR2, il SET CARATTERE è 'WE8MSWIN1252' e il SET CARATTERE NAZIONALE è 'AL16UTF16'. Sembra che il driver non rilevi correttamente il set di codifica nelle variabili sopra. Il controllo degli attributi 'encoding' e 'nencoding' sulla connessione restituisce 'US-ASCII' in entrambi i casi che non è corretto. Ricevo ancora lo stesso errore DatabaseError quando provo a NLS_LANG su 'AL16UTF16', che dal momento che la mia connessione allo schema è rimossa (e sarà anche in produzione) spiega perché non è possibile accedere a questi file. – snarkyname77
Nella mia situazione, il mio risultato dalla query precedente è "AMERICAN_AMERICA.US7ASCII". Tuttavia, i miei inserti Unicode hanno iniziato a funzionare correttamente una volta che il mio NLS_LANG era impostato su "_.AL32UTF8" (senza virgolette). – davidjb
Il mio risultato dalla query precedente è AMERICAN_AMERICA.WE8MSWIN1252. @davidjb, come lo si imposta a quel valore senza virgolette. Cosa hai importato nel tuo scope per ottenerlo? – ThatAintWorking