9

私のアプリケーションでは、「テキスト」列を持つpostgresqlデータベーステーブルを使用して、ピクルされたpythonオブジェクトを保存しています。データベースドライバーとして私はpsycopg2を使用していますが、今まではpython-strings(unicode-objectsではなく)のみをDBに渡し、DBから文字列を取得していました。これは、最近、文字列処理をより適切/正しい方法にすることを決定し、次の構成を DB レイヤーに追加するまで、基本的にはうまく機能しました。

psycopg2.extensions.register_type(psycopg2.extensions.UNICODE)
psycopg2.extensions.register_type(psycopg2.extensions.UNICODEARRAY)

これは基本的に、アプリケーションのどこでも問題なく機能し、現在可能な限りユニコード オブジェクトを使用しています。

しかし、ピクルされたオブジェクトを含むテキスト列のこの特別なケースでは、問題が発生します。私はこのように私のテストシステムでそれを動作させました:

  • データの取得: SELECT data::bytea, params FROM mytable
  • データの書き込み: execute("UPDATE mytable SET data=%s", (psycopg2.Binary(cPickle.dumps(x)),) )

...しかし、残念ながら、運用システムの一部の列の SELECT でエラーが発生しています。

psycopg2.DataError: invalid input syntax for type bytea

このエラーは、psql シェルでクエリを実行しようとしたときにも発生します。

基本的には列を「text」から「bytea」に変換する予定ですが、上記のエラーによりこの変換もできません。

私が見る限り、(列を純粋なpython文字列として取得する場合)文字列には ord(c)<=127 の文字のみがあります。

4

1 に答える 1

16

問題は、キャストtextbytea文字列内のバイトを取得して値として組み立てるという意味ではなくbytea、代わりに文字列を取得して、bytea型へのエスケープされた入力値として解釈することです。bytea主に pickle データにバックスラッシュが多く含まれており、特別に解釈されるため、これは機能しません。

代わりにこれを試してください:

SELECT convert_to(data, 'LATIN1') ...

byteaこれにより、文字列が LATIN1 エンコーディングのバイト シーケンス (値) に変換されます。すべて ASCII であるため、正確なエンコーディングは問題ではありません (ただし、ASCIIエンコーディングはありません)。

于 2013-10-10T20:39:16.990 に答える