17

Oracle スキーマに Unicode を挿入する際に問題が発生しています。データベースは Oracle 11g インスタンスだと思いますが、現時点では確信が持てません。私はOS X 10.6.8でpython 2.6.1を使用しており(これはpythonのシステムバージョンです)、sourceforge.netからダウンロードしたcx-Oracleドライバーモジュールバージョン5.1を使用して、ビルドしてvirtualenv 1.6.1インスタンスにインストールしていますサイト パッケージが表示されます。私のスクリプトは次のとおりです

  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 にデコードします。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 を処理する方法をよりよく理解するために探し回ったところ、sourceforge.net からダウンロードした cx-Oracle ソースの HISTORY.txt でこれを見つけました。

5.0.4 から 5.1 への変更点
1) UNICODE モードのサポートを削除し、文字列が渡される可能性のあるすべての場所で Unicode を通過できるようにします。これは、文字列が Python の NLS_LANG 環境変数の値を使用して Oracle に渡されることを意味します。 3.x も同様です。これにより、UNICODE モードを使用することで発見された一連の問題が解消され、たとえば接続文字列や SQL ステートメントで Unicode を使用できないという Python 2.x の不要な制限も取り除かれました。...

私の仮定では、NLS_LANG 環境変数が「ascii」または同等の値に設定されているため、NLS_LANG を「AL32UTF8」に設定してみてください。これは Unicode の正しい値であると思われ、接続を作成する前に新しい値を設定します。

  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 グループに行く前に、問題の内容をよりよく理解したいと考えています。

ありがとう、

4

1 に答える 1

15

環境変数の設定は正しい方法ですが、「AL32UTF8」は NLS_LANG の正しい値ではありません。Oracle のインスタンスで使用されている NLS_LANG の正しい値を取得するには、次のコマンドを実行します。

SELECT USERENV ('language') FROM DUAL  
于 2013-04-04T05:49:34.820 に答える