ユニコードをOracleスキーマに挿入する際に問題が発生しました。データベースはOracle 11gインスタンスですが、現時点では不明です。私はOS X 10.6.8でPython 2.6.1を使用しています(これはPythonのシステムバージョンです)。sourceforge.netからダウンロードしたcx-Oracleドライバモジュールバージョン5.1を使用しています。これは、virtualenv 1.6.1インスタンスサイトパッケージが表示されます。cx-Oracleを使用してUnicodeを挿入できません
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)
私はタイプNUMBERおよびNCLOBのIDとテキストフィールドでテストテーブルを作成するために文を実行し、カーソルを作成し、接続を作成し、以下のように私のスクリプトです。 UTF-8でエンコードされたテキストであることがわかっているファイルを開き、その文字列をUnicodeにデコードします。 ユニコード文字列に挿入文を作成し、その文を実行すると結果はこのエラーです。
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)
何かが、Oracleスキーマに挿入する前に、文をASCIIとしてエンコードしようとしています。だから私は、CX-Oracleがどのように処理するかをよりよく理解するためにUnicodeを探して周り狩り始めたと私は
変更5.0.4から5.1
にsourceforge.netからダウンロードしたCX-OracleソースのHISTORY.TXTでこれを見つけました1)UNICODEモードのサポートを削除し、 Unicodeを通過させるために、 の文字列を渡すことができます。これは、NLS_LANG環境の値を使用して という文字列がOracleに渡されることを意味します。 Python 3.x同じように。これにより、UNICODEモードを使用して発見された問題 が削除され、Python 2.xで不要な の制限が取り除かれました。たとえば、接続文字列 やSQL文でUnicodeを使用できませんでした。 ...
私の仮定は、NLS_LANG環境変数が「ASCII」または何らかの同等に設定されているので、私はユニコードの正しい値であると考えている「AL32UTF8」にNLS_LANGを設定してみてください、と設定されていることです私の接続を作成する前に新しい値。
os.environ["NLS_LANG"] = "AL32UTF8"
connection = cx_Oracle.connect(
"<user>/<password>@<host>/<service-name>"
)
cursor = connection.cursor()
...
このエラーが発生します。
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
NLS_LANGの値を改ざんできないようです。
ここに私の質問があります。間違った列型のような簡単なものがありますか? cx-Oracleドライバに問題がありますか? cx-Oracleモジュールをビルドするときに "WITH_UNICODE"環境変数を設定する必要がありますか? Oracleインスタンスの問題ですか? Oracleに関する経験はほとんどなく、OracleとPythonを一緒に使用したことはありません。私はこの問題に取り組むのに2日間を費やしており、DBAグループに行く前に問題が何であるかをよりよく理解したいと思います。環境変数を設定する
おかげで、
私のDBAからの回答がありました。私たちの11gR2インストールの場合、CHARACTER SETは 'WE8MSWIN1252'で、NATIONAL CHARACTER SETは 'AL16UTF16'です。ドライバは、上記の変数のエンコーディングセットを正しく検出していないようです。どちらの場合も、接続の 'encoding'属性と 'nencoding'属性が「US-ASCII」であることを確認すると正しくありません。 NLS_LANGを 'AL16UTF16'にしようとすると、同じDatabaseErrorが得られます。なぜなら、スキーマへの接続が削除されているからです(そして実稼働環境にもあります)。なぜこれらのファイルにアクセスできないのかを説明します。 – snarkyname77
私の状況では、上記のクエリの結果は "AMERICAN_AMERICA.US7ASCII"です。しかし、NLS_LANGが "_.AL32UTF8"(引用符なし)に設定されると、私のUnicode挿入が正しく動作するようになりました。 – davidjb
上記のクエリの結果はAMERICAN_AMERICA.WE8MSWIN1252です。 @davidjb、どうやってその値を引用符なしに設定しますか?あなたはそれを得るためにあなたのスコープに何をインポートしましたか? – ThatAintWorking