質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1501閲覧

python3.5, psycopg2でUnicodeDecodeError

mochi9902

総合スコア29

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2017/10/01 15:13

python3.5を使用して、DBに画像を含むデータを登録する部分を作成しています。

python

1def insertItemInfo(itemno, title, url, price, content, filename1, filename2, filename3, dirname1, dirname2, dirname3, dt): 2 try: 3 cnn = psycopg2.connect(dataSource) 4 cur = cnn.cursor() 5 6 # デバッグ用ここから 7 print(str(itemno).encode('utf-8')) 8 print(title) 9 print(url.encode('utf-8')) 10 print(price) 11 print(content) 12 print(filename1.encode('utf-8')) 13 print(filename2.encode('utf-8')) 14 print(filename3.encode('utf-8')) 15 print(dirname1.encode('utf-8')) 16 print(dirname2.encode('utf-8')) 17 print(dirname3.encode('utf-8')) 18 print(dt) 19 #ここまで 20 21 pic1 = u"" 22 pic2 = u"" 23 pic3 = u"" 24 if len(filename1) != 0 and len(dirname1) != 0: 25 f1 = open( dirname1 + "/" + filename1, 'rb') 26 pic1 = f1.read() 27 f1.close() 28 if len(filename2) != 0 and len(dirname2) != 0: 29 f2 = open( dirname2 + "/" + filename2, 'rb') 30 pic2 = f2.read() 31 f2.close() 32 if len(filename3) != 0 and len(dirname3) != 0: 33 f3 = open( dirname3 + "/" + filename3, 'rb') 34 pic3 = f3.read() 35 f3.close() 36 cur.execute("""INSERT INTO ITEM_INFO VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, 37 'owner', 'pythonTool', %s, 'owner', 'pythonTool', %s)""", 38 (str(itemno).encode('utf-8'), title, url.encode('utf-8'), price, content, psycopg2.Binary(pic1), psycopg2.Binary(pic2), psycopg2.Binary(pic3), 39 filename1.encode('utf-8'), filename2.encode('utf-8'), filename3.encode('utf-8'), dirname1.encode('utf-8'), dirname2.encode('utf-8'), dirname3.encode('utf-8'), dt, dt,)) 40 cnn.commit() 41 42 cur.close() 43 cnn.close() 44 except (psycopg2.OperationalError) as e: 45 print(e)

ネット上で、psycopg2ではバイナリーとして扱うと記載があったので、
encode('utf-8')を行ってバイト型に揃えています。

それでも実行時に以下のエラーが発生してしまいます。

ーーーーー
b'5'
b"title"
b'url'
210.00
b"contents\n samples"
b'201710012348_0_0.jpg'
b''
b''
b'201710012348'
b''
b''
2017-10-01 23:50:08.970017
Unhandled exception in thread started by <bound method Thread._bootstrap of <Thread(Thread-3, started 8472)>>
Traceback (most recent call last):
<中略>
File "C:\fakePath\parse\dbTransaction.py", line 68, in insertItemInfo
TypeError: can't escape str to binary

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
<中略>
File "C:\fakePath\Python35\lib\codecs.py", line 321, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8e in position 6599: invalid start byte

ーーーーー

ここでいう、"C:\fakePath\parse\dbTransaction.py", line 68, in insertItemInfo
の部分が、上記ソースコードでのcur.execute(...)に当たります。

解決策をお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Win10
PostgreSQL 9.3.10, compiled by Visual C++ build 1600, 64-bit
Python 3.5.4 :: Anaconda custom (64-bit)
psycopg2==2.7.3.1

にて簡単な動作確認を行いましたが、エラーなく画像データ登録できました。
なお、DB登録する文字列はutf-8にエンコードせずにstr型をそのまま渡して問題ありませんでした。
まずは単純なDBでバイナリ(画像)を登録できるか確認することをお勧めします。

参考 : Psycopg2でPostgreSQL 9.3.2のbytea型の列にバイナリデータを登録する

DB

-- CREATE DATABASE test WITH OWNER = hoge ENCODING = 'UTF8' TABLESPACE = pg_default LC_COLLATE = 'C' LC_CTYPE = 'C' CONNECTION LIMIT = -1; -- CREATE TABLE t_bin ( image bytea, id integer NOT NULL, name character varying(255), CONSTRAINT t_bin_p_key PRIMARY KEY (id) ) WITH ( OIDS=FALSE ); ALTER TABLE t_bin OWNER TO hoge;

Python

1import psycopg2 2 3con = psycopg2.connect('dbname=test user=hoge password=hoge') 4cur = con.cursor() 5 6#cur.execute("delete from t_bin") 7pic = open('lena.jpg', 'rb').read() 8cur.execute("INSERT INTO t_bin (id,name,image) values (%s,%s,%s)", (1,'あいう',psycopg2.Binary(pic))) 9con.commit() 10 11# 結果 12# (<memory at 0x00000260C2ED8E88>, 1, 'あいう') 13cur.execute("select * from t_bin") 14for row in cur: 15 print(row) 16 17cur.close() 18con.close()

投稿2017/10/02 05:03

can110

総合スコア38233

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問