2008年5月9日金曜日
DatePropertyにはやはり不具合(bug)あり
date = db.DateTimeProperty(auto_now_add=True) の値が
対象の datastore のデータを更新する度に、時刻が進んでいってしまう現象は
以下の Patch により直った。 ( SDK 1.0.1)
DateProperty does not work properly in dev environment
http://code.google.com/p/googleappengine/issues/detail?id=131
c:/Program Files/Google/google_appengine/google/appengine/api/datastore_types.py
I tried a patch to module datastore_types.py, which seems to work:
change line 1033
from
lambda val: datetime.datetime.fromtimestamp(float(val) / 1000000.0),
to
lambda val: datetime.datetime.utcfromtimestamp(float(val) / 1000000.0),
Per the Python doc, fromtimestamp() converts to the local timezone.
2008年5月2日金曜日
Key names and IDs cannot be used like property values
key と key_name と ID があり、これを理解していないいけない。
GQL で key は select できるが、 key_name や ID は select できない。
・ select してきた key から key_name や ID を知ることはできる。
・ 検索条件に ID や key_name を指定することができる。
・ 検索条件に key を指定することは GQL ではできない。
注意: datastore には2つある
from google.appengine.ext import db これが GQL api の解説あり
from google.appengine.api import datastore これは cccwiki のサンプルなどで使用されている
key_name 指定して put すると
ID は空欄で、Key_Name に値が保存される。
import sys #import sys module for printing to stdout
from google.appengine.ext import db
class Car(db.Model):
brand = db.StringProperty(required=True)
wheels = db.ListProperty(db.Key)
mercedes = Car(brand="Mercedes", key_name ="b")
# mercedes.put()
print >> sys.stdout, mercedes.brand
select = mercedes.get_by_id( 130 )
print >> sys.stdout, select.brand
select = mercedes.get_by_key_name( "b" )
print >> sys.stdout, select.brand
id = 130
select = Car.get(db.Key.from_path('Car', id))
print >> sys.stdout, select.brand
key_name = "b"
select = Car.get(db.Key.from_path('Car', key_name))
print >> sys.stdout, select.brand
print >> sys.stdout, select.key()
print >> sys.stdout, select.key().id()
print >> sys.stdout, select.key().name()
select * from Greeting where key = "xxxx"
select * from Greeting where id = xxx
のような検索はできない。
select user_name from Greeting where id = xxxx
update Greeting set user_name = 'new name' where id = xxxx
のかわりに
greetings = db.GqlQuery("SELECT * FROM Greeting")
id = greeting.key().id()
id = int(self.request.get('id'))
greeting = Greeting.get(db.Key.from_path('Greeting', id))
row id から再度検索する必要なない。
get(db.Key.from_path('Greeting', id) これが再検索と同じ
key さえわかれれば db.get() で OK
from google.appengine.ext import db
r = db.get("agpoZWxsb3dvcmxkcgsLEgRCbG9nGNQBDA")
print r.title
Tip: Key names and IDs cannot be used like property values in queries. However, you can use a named key, then store the name as a property. You could do something similar with numeric IDs by storing the object to assign the ID, getting the ID value using obj.key().id(), setting the property with the ID, then storing the object again.
http://code.google.com/appengine/docs/datastore/keysandentitygroups.html#Kinds_Names_and_IDs
http://code.google.com/appengine/articles/djangoforms.html
追加仕様検討
Issue 178: Add unique=True/False to db.property constructor to ensure uniqueness
http://code.google.com/p/googleappengine/issues/detail?id=178
Trunsaction / run_in_transaction
http://code.google.com/appengine/docs/datastore/functions.html#run_in_transaction
2008年5月1日木曜日
Google App Engine / ワイルドカード検索
部分一致検索はできないようだが、擬似的に行うことができる。
ただ、これも unicode がからむと少々注意が必要
下記を参考に helloworld.py にてテストしたが、
#!-*- coding:utf-8 -*- がきいているためか、
OK
greetings = db.GqlQuery("SELECT * FROM Greeting where content >= :1 and content < :2 ",
search_key, search_key + u"\uFFFD" )
NG
# greetings = db.GqlQuery("SELECT * FROM Greeting where content >= :1 and content < :2 ", # search_key, urllib.unquote(search_key).decode("utf8") + u"\uFFFD" )
でした。 http://code.google.com/appengine/docs/datastore/queriesandindexes.html
Tip: Query filters do not have an explicit way to match just part of a string value, but you can fake a prefix match using inequality filters:db.GqlQuery("SELECT * FROM MyModel WHERE prop >= :1 AND prop < :2", "abc", "abc" + "\xEF\xBF\xBD")
This matches every MyModel entity with a string property prop that begins with the characters abc. The byte string "\xEF\xBF\xBD" represents the largest possible Unicode character. When the property values are sorted in an index, the values that fall in this range are all of the values that begin with the given prefix.
http://groups.google.com/group/google-appengine/browse_thread/thread/47abf4b8842ab865?hl=en
Next problem is that I can't search the datastore with a parameter
from the query string, something like this:
import urllib
q = "Ambj%C3%B6" # Url encoded u"Ambjö"
fsgs = db.GqlQuery("SELECT * FROM Fsg WHERE fsg >= :1 AND fsg < :2", urllib.unquote(q), urllib.unquote(q) + u'\uFFFD')
Works perfect if I only have ascii characters. Is urllib.unquote wrongutility for this?
> q = "Ambj%C3%B6" # Url encoded u"Ambjö"
> fsgs = db.GqlQuery("SELECT * FROM Fsg WHERE fsg >= :1 AND fsg < :2", > urllib.unquote(q), urllib.unquote(q) + u'\uFFFD')
returns isn't a Unicode string either, so you need to convert it to
Unicode. Eg:
urllib.unquote(q).decode("utf8") + u"\uFFFD"
2008年4月29日火曜日
Google App Engine / 管理コンソール
Docs > The Dev Web Server
以下の URL で開発環境の Development Console にアクセスし、datastore の内容を確認することができる。
http://localhost:8080/_ah/admin
http://localhost:8080/_ah/admin/datastore?kind=Greeting
このプログラムのソース
c:/Program Files/Google/google_appengine/google/appengine/ext/admin/__init__.py
2008年4月26日土曜日
Google App Engine / django template カスタムタグ
django のテンプレートをカスタマイズすることができた。
(django template にカスタム filter を追加することができた)
-- templatefilters.py
#!-*- coding:utf-8 -*-
# import the webapp module
from google.appengine.ext import webapp
import datetime
# get registry, we need it to register our filter later.
register = webapp.template.create_template_register()
def truncate(value,maxsize,stopper = '...'):
""" truncates a string to a given maximum
size and appends the stopper if needed """
stoplen = len(stopper)
if len(value) > maxsize and maxsize > stoplen:
return value[:(maxsize-stoplen)] + stopper
else:
return value[:maxsize]
def timeJST (value):
# return value - datetime.timedelta(hours=18)
return value + datetime.timedelta(hours=9)
# SDK102 にしたら動作がかわった???
register.filter(truncate)
register.filter(timeJST)
-- index.html
{{ greeting.date|timeJST|date:"Y/m/d H:i:s" }}
-- helloworld.py
webapp.template.register_template_library( 'templatefilters')
参照元
- Django: Custom tag libraries?
http://groups.google.com/group/google-appengine/browse_thread/thread/41ddd1a0cce0a81d?hl=en - Using custom django template helpers with Google APP Engine
http://daily.profeth.de/2008/04/using-custom-django-template-helpers.html
2008年4月25日金曜日
Google App Engine / flickr API 表示サイズ
http://www.flickr.com/services/api/ で検索結果の画像の表示のサイズの変更について、テストした結果をメモしておく。
テンプレートの変更による。 ( 送信するパラメータは変更なし)
検索キーワードは "Michaelangelo Moses" を設定
- s small square 75x75
- t thumbnail, 100 on longest side
- m small, 240 on longest side
- - medium, 500 on longest side
- b large, 1024 on longest side (only exists for very large original images)
- o original image, either a jpg, gif or png, depending on source format
http://www.flickr.com/services/api/misc.urls.html にまとめられていました。
http://dflatt.org/eric/2006/12/flickr_api.html こちらもわかりやすい。
/sizes/
_m.jpg
- 拡張子なし。
- これが一番大きな検索結果が表示された。
/sizes/l/
_b.jpg
- _b.jpg だと一部の画像が表示されない
- UNAVAILABLE の表示であっても、クリックした先の flickr のサイトの画像は表示される。
/sizes/sq/
_s.jpg
/sizes/t/
_t.jpg
/sizes/o/
_o.jpg
- UNAVAILABLE の表示
- クリック : flickr のサイトのオリジナルサイズの画像が表示される。
2008年4月24日木曜日
Google App Engine / url fetch API
先日のサンプルプログラムはあきらめ URL Fetch API用の別の以下のプログラム
Google App EngineでXMLをパースする方法(python版WebService::Simpleを使ってflickr画像検索を作る) のサンプルは動作させることができた。
http://localhost:8080/flickr/
Flickr の API Key も http://www.flickr.com/services/から取得
いろいろな API http://www.flickr.com/services/api/ が用意
されている。
プロジェクトフォルダ以下のファイルリスト
│ app.yaml
│ flickr.html
│ flickr.py
│ index.yaml
│ webSimple.py
│ webSimple.pyc
│
└─elementtree
ElementInclude.py
ElementPath.py
ElementPath.pyc
ElementTree.py
ElementTree.pyc
HTMLTreeBuilder.py
SgmlopXMLTreeBuilder.py
SimpleXMLTreeBuilder.py
SimpleXMLTreeBuilder.pyc
SimpleXMLWriter.py
TidyHTMLTreeBuilder.py
TidyTools.py
XMLTreeBuilder.py
__init__.py
__init__.pyc
--
SDK102 にしたところ、下記のエラーで動作しなくなる
'photos' : res.parse_xml().find("photos").getchildren(),
AttributeError: 'NoneType' object has no attribute 'getchildren'
登録:
投稿 (Atom)
Swift UI チュートリアル Loading watchOS が終わらない?
Loading watchOS が終わらない? ディスク容量の残量が少ないので不要なシュミレーターを削除したとこころ watchOSのものが全部なくなってしまっていた。 WatchOS を削除して再度インストールしても復活せず。 Create a new simulator で ...
-
1. get_or_insert 自体がトランザクションなのでこれを含めたトランザクションを 作成しようとするとエラーとなる。 File "C:\Program Files\Google\google_appengine\google\appengine\api\...
-
新しいXcodeが使いたかったので MacOS15(Sequoia) にアップグレードしたところ、やはりApacheでPHPが動かなくなっていた。 結論としては brew, openssl, php, httpd を全て再度インストールしたところ動くようになった。 以下、作業ロ...
-
Apache が動かなくなった (MacOS 13.6.7) /var/log/apache2/access_log も error_log も出力されなくなっている $ sudo apachectl start すると以下のようなエラーとなった。 Load failed: ...