DataStoreに日本語を登録する方法

285 views
Skip to first unread message

Sumio Ebisawa

unread,
Jun 22, 2009, 9:06:43 PM6/22/09
to Google-App-Engine-Japan
海老澤と申します。お世話になります。

GoogleAppEngineのテスト環境で日本語をDataStoreに登録しようと苦戦しております。皆様のアドバイスを頂戴できれば幸いで
す。

=================================================================

◆環境
・CentOS 5.3
・Python 2.5(ソースからインストール)
・テスト環境は1.1.1

◆サンプルスクリプト(UTF-8で保存)

# -*- coding : utf-8 -*-

from google.appengine.ext import db

### アプリのデータ形式
class Fruits(db.Model):
name = db.StringProperty()

### データ登録
fruit = Fruits()
fruit.name = 'ばなな'
fruit.put();

### 登録内容の表示
recs = db.GqlQuery("SELECT * FROM Fruits")
for rec in recs:
print rec.name

◆エラーメッセージ
<type 'exceptions.UnicodeDecodeError'>: 'ascii' codec can't decode
byte 0xe3 in position 0: ordinal not in range(128)
args = ('ascii', '\xe3\x81\xb0\xe3\x81\xaa\xe3\x81\xaa', 0, 1,
'ordinal not in range(128)')
encoding = 'ascii'
end = 1
message = ''
object = '\xe3\x81\xb0\xe3\x81\xaa\xe3\x81\xaa'
reason = 'ordinal not in range(128)'
start = 0

=================================================================

要は「ASCIIで表現できない文字がある」ということらしいです。

上記スクリプトの「fruit.name = 'ばなな'」を「fruit.name = 'banana'」とすれば問題なく動きます。
また「fruit.name = u'ばなな'」としてもダメでした。

検索したら http://d.hatena.ne.jp/satoru_net/20090521/1242881979 を見つけたので、
これを参考にして次のように修正しましたが、変わらずです。
fruit.name = db.Text('ばなな', encoding="utf-8");

しかし、POST等でユーザから入力された文字列は問題なく表示されます。

もし、解決方法をご存じの方がいらっしゃれば、アドバイスを頂戴できれば幸いです。

Takashi Matsuo

unread,
Jun 22, 2009, 9:46:45 PM6/22/09
to google-app-...@googlegroups.com
松尾です。

下記の行を
# -*- coding : utf-8 -*-
下記のようにするとどうですか
# -*- coding: utf-8 -*-
(coding の後のスペースを無くす)

Happy coding :-)

-- Takashi Matsuo



2009/6/23 Sumio Ebisawa <sebisawa...@gmail.com>:

Hiroaki Kawai

unread,
Jun 22, 2009, 10:29:50 PM6/22/09
to google-app-...@googlegroups.com
川井です。

まず
fruit.name = 'ばなな'

fruit.name = u'ばなな'
です。

fruit.name = db.Text('ばなな', encoding="utf-8");

これは良くないです。
fruit.name = db.Text(u'ばなな');
か、
fruit.name = db.Text(u'ばなな'.encode("UTF-8"), encoding="utf-8");
でしょう。encoding パラメータを使うべき時なのは、第一引数が
バイト列として入力として渡ってきた時(たとえばユーザの form submit 等)のみのはずです。

Exception が何行目で出ているのかわからないですが、print で出ているのであれば、
sys.out の文字セットが ascii になっているからだったと思います。
# 行番号は出力に出ているはずなので、メールするときはそれも含めていただきたいところ。

from google.appengine.ext import webapp
の response.out.write() で書く場合は UTF-8 がデフォルトになっていて
変換されているので、私は普段はそちらを使っています。

Sumio Ebisawa

unread,
Jun 23, 2009, 12:16:07 PM6/23/09
to Google-App-Engine-Japan
海老澤です。


皆様、アドバイスありがとうございます。次のように修正したら、
問題なく動作したことをご報告いたします。

==============================================================

# -*- coding: utf-8 -*-

from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

### アプリのデータ形式
class Fruits(db.Model):
name = db.StringProperty()

### データ登録とページ表示
class MainPage(webapp.RequestHandler):
def get(self):
### データ登録
fruit = Fruits()
fruit.name = u'ばなな'
fruit.put();

### 登録内容の表示
recs = db.GqlQuery("SELECT * FROM Fruits")
for rec in recs:
self.response.out.write( rec.name )

### Webアプリの制御
application = webapp.WSGIApplication([
('/test', MainPage)
], debug=True)

def main():
run_wsgi_app(application)

if __name__ == '__main__':
main()

==============================================================

主な変更点は次の通りです。
1)スクリプト上部の文字コード指定部分「# -*- coding: utf-8 -*-」の「coding」の
  後ろのスペースを除去
2)結果出力時にprintを使わず「self.response.out.write」を利用

上記のどちらかが欠けても正しく動作しないようです。
Reply all
Reply to author
Forward
0 new messages