bulkloaderを使用してDataStoreにインポートしようとするときに、GeoPtプロパティが含まれていると失敗する現象が発生していました。
bulkloader.Loaderを継承してカンマ区切り文字列として渡してもダメで、
挙句の果てにはbulkloader.py --dump でダンプしたデータをrestoreしても失敗していました。
一度データを入れたアプリを落として、再度起動するとデータのリストアに失敗して立ち上がらなくなってしまうので、
これは根本的に駄目だなと。
ちなみに発生していたエラーはこんな感じ。
"unpack requires a string argument of length 8"
でこのエラーを頼りにググって調べた結果、Pythonのバージョンによるものだと。
http://code.google.com/p/googleappengine/issues/detail?id=401
というわけで、AppEngineのpython設定を2.6に切り替えたらうまく動きました。
2010年4月26日月曜日
2009年6月28日日曜日
GAEでphpのprint_rみたいな出力
phpではprint_rで配列や連想配列の中身を確認することが多いのですが、
pythonではそれに相当するものがなくデバッグに苦労しがちです。
そんなときには、配列や連想配列をjson形式で出力することで、同等に近い表示を行うことができます。
jsonへ変換するときに、indentを設定してあげて見やすくするのと、
unicode文字列をasciiへエスケープする設定をoffにしています。
出力結果はこんな感じです。
pythonではそれに相当するものがなくデバッグに苦労しがちです。
そんなときには、配列や連想配列をjson形式で出力することで、同等に近い表示を行うことができます。
from google.appengine.ext import webapp
from django.utils import simplejson
def print_r(obj):
return simplejson.dumps( obj,indent=4,ensure_ascii=False)
class MainHandler(webapp.RequestHandler):
def get(self):
obj = {
"name" : "sample name",
"desc" : "sample desc",
"option" : {
"val1" : "value1",
"val2" : "value2",
"val3" : 333,
},
"arrary" : [
1,2,3,4,5
],
}
self.response.out.write( '<pre>' + print_r(obj) + '</pre>' )
jsonへ変換するときに、indentを設定してあげて見やすくするのと、
unicode文字列をasciiへエスケープする設定をoffにしています。
出力結果はこんな感じです。
{
"arrary": [
1,
2,
3,
4,
5
],
"name": "sample name",
"option": {
"val3": 333,
"val2": "value2",
"val1": "value1"
},
"desc": "sample desc"
}
2009年6月21日日曜日
Google App Engine でセッションを扱う方法
gaeutilitiesというプロジェクトで実現しています。
http://gaeutilities.appspot.com/
使い方はこんな感じ
セッションの有効期間や
トークンをクッキーに保存するときの名称、
IPによるセッションの有効チェックなどを
初期化時に設定できるようです。
ざっとソースコードを眺めた感じ、cookie+storage+memcacheで実装されているようです。
同じようなコードを書いてしまいがちですが、車輪の再発明は避けたいですね。
http://gaeutilities.appspot.com/
使い方はこんな感じ
#初期化
from appengine_utilities.sessions import Session
self.session = Session()
#セッションへ格納
session['key1'] = 'value1'
#セッションに格納されているか確認
if 'key2' in session:
#セッションの値を出力
print session['key2']
セッションの有効期間や
トークンをクッキーに保存するときの名称、
IPによるセッションの有効チェックなどを
初期化時に設定できるようです。
ざっとソースコードを眺めた感じ、cookie+storage+memcacheで実装されているようです。
同じようなコードを書いてしまいがちですが、車輪の再発明は避けたいですね。
2009年6月16日火曜日
URLFetchでPostする方法
urlfetchに引数を指定することでPostを投げる事もできます。
パラメータはpayloadに指定します。
urllib.urlencodeで文字列を生成することができます。
パラメータはpayloadに指定します。
urllib.urlencodeで文字列を生成することができます。
from google.appengine.api import urlfetch
import urllib
url = u'http://example.com/'
payload = urllib.urlencode( {
'param1' : 'value1',
'param2' : 'value2',
} )
response = urlfetch.fetch( url , payload , urlfetch.POST )
2009年5月31日日曜日
ElementTreeを使ってXMLを読み込む
マッシュアップには欠かせない、XMLのパース方法です。
xml.etree.ElementTreeを使います。
xml.etree.ElementTreeを使います。
import xml.etree.ElementTree as etree
xml = """
<test>
<name>sample name</name>
<desc type='text'>sample desc</desc>
<option>
<value>value1</value>
</option>
<option>
<value>value2</value>
</option>
<option>
<value>value3</value>
</option>
</test>
"""
elem = etree.fromstring(xml)
self.response.out.write( '<br />name=' + elem.findtext('name') )
self.response.out.write( '<br />desc=' + elem.findtext('desc'))
self.response.out.write( '<br />desc=' + elem.find('desc').text)
self.response.out.write( '<br />desc type=' + elem.find('desc').get('type') )
for opt in elem.findall('option'):
self.response.out.write('<br />option ' + opt.find('value').text )
2009年5月17日日曜日
Google Accounts のユーザー名は表示できない?
Google Accounts というGoogle の認証システムを使える便利な機能があるのですが、、、
http://code.google.com/appengine/docs/python/users/
これを使って、利用者本人を認証する分にはまったく問題ないのですが、
例えば、投稿データをこのUserクラスと関連づけようとすると問題が出てきます。
初期化のための変数が、emailアドレスしかないんですね。
ということは、ユーザー○○の投稿一覧ページなんかを作ろうとすると、
URLにemailアドレスを入れないといけない?
ということになってしまうような。。。
さらにnicknameというプロパティがあるのですが、
これもemailアドレスの@の前部分が返ってくるだけだし、
変更する機能なども特にサポートされていないようなんですね。
なので、何も考えずにユーザー投稿サイトを作ってしまうと、
gmailアドレスがダダ漏れなサイトになってしまいます。
emailアドレスは独自の暗号化して復元できないようにして、
nicknameは独自の編集機能を設けて
と自分で作り込むしかなさそうです。
Google Friend Connectとの連携が簡単にできるようになったりしないですかね?
http://code.google.com/appengine/docs/python/users/
これを使って、利用者本人を認証する分にはまったく問題ないのですが、
例えば、投稿データをこのUserクラスと関連づけようとすると問題が出てきます。
初期化のための変数が、emailアドレスしかないんですね。
ということは、ユーザー○○の投稿一覧ページなんかを作ろうとすると、
URLにemailアドレスを入れないといけない?
ということになってしまうような。。。
さらにnicknameというプロパティがあるのですが、
これもemailアドレスの@の前部分が返ってくるだけだし、
変更する機能なども特にサポートされていないようなんですね。
なので、何も考えずにユーザー投稿サイトを作ってしまうと、
gmailアドレスがダダ漏れなサイトになってしまいます。
emailアドレスは独自の暗号化して復元できないようにして、
nicknameは独自の編集機能を設けて
と自分で作り込むしかなさそうです。
Google Friend Connectとの連携が簡単にできるようになったりしないですかね?
2009年5月9日土曜日
unicodeとstringだけじゃない、db.Textはまた別です
UnicodeとStringが別物という話はpythonの世界では有名なようですが
GAEにはもう一つテキストを表す型があります。
ストレージに長い文字列を保管することができるTextPropertyがそれです。
一見するとStringと同じように動作するので紛らわしいのですが、直接Unicodeに変換することができず、一度stringに変換してあげる必要がありますので注意が必要です。
Unicode で萎えそうになったとき(orz)に思い出してほしい5つのこと - Solr, Python, MacBook Airより引用:
Unicode 関係でモヤモヤしたら思い出してください。
- Unicode と UTF-8 はまったくの別物であることを認識しよう。
- Python プログラム内部で使うときは Unicode で統一しよう。
- プログラムから外部に書き出すときは UTF-8 に変換しよう。
- self.request.get()で得られるデータの文字コードは Unicode だよ。
- urlfetch.fetch()で得られるデータの文字コードは、不定だよ。
GAEにはもう一つテキストを表す型があります。
ストレージに長い文字列を保管することができるTextPropertyがそれです。
一見するとStringと同じように動作するので紛らわしいのですが、直接Unicodeに変換することができず、一度stringに変換してあげる必要がありますので注意が必要です。
from google.appengine.ext import db
text = db.Text(u'あいうえお')
#これはエラー
#print text
#stringへ変換はOK
str = text.encode('utf-8')
print type(str) #
#unicodeへ直接変換できない
#uni = text.decode('utf-8')
#stringへencodeしてからdecodeしてunicodeへ変換可能
uni = text.encode('utf-8').decode('utf-8')
print type(uni)
登録:
投稿 (Atom)