2008年12月25日木曜日
IIS + MySql
2008年12月22日月曜日
2008年12月18日木曜日
SOQL Questions
Also, how do you check for NULL in a WHERE clause. I know IS NULL does not work?
A. SELECT Id FROM CASE WHERE Id <> null
or
SELECT Id FROM CASE WHERE Id = null
don't think there's anything like distinct though
http://community.salesforce.com/sforce/board/message?board.id=NET_development&message.id=2406&query.id=8066#M2406
Q. Join
Accessing Query Results from a Relationship Query from the Partner WSDL with Axis for Java
http://wiki.apexdevnet.com/index.php/Accessing_Query_Results_from_a_Relationship_Query_from_the_Partner_WSDL_with_Axis_for_Java
Q. Update many rows
sql = "select id from Product2 where ProductCode like '%.jp%' and Family <> 'blog' "
query_result = client.query( sql )
if ( query_result['records'].__len__() < 1 ):
self.response.out.write('no product found with : %s ' % sql )
else :
products = query_result['records']
for product in products:
product['Family'] = 'blog'
results = client.update( product )
self.response.out.write( results )
if results[0]['success'] :
self.response.out.write( 'updated. ' )
else:
self.response.out.write( results[0]['errors'] )
self.response.out.write( 'Error. ' )
2008年12月17日水曜日
Cannot build indexes that are in state ERROR.
Error 400: --- begin server output ---
Cannot build indexes that are in state ERROR.
To vacuum and rebuild your indexes:
1. Create a backup of your index.yaml specification.
2. Determine the indexes in state ERROR from your admin console: http://appengine.google.com/datastore/indexes?&app_id=blog-editor
3. Remove the definitions of the indexes in ERROR from your index.yaml file.
4. Run "appcfg.py vacuum_indexes your_app_dir/"
5. Wait until the ERROR indexes no longer appear in your admin console.
6. Replace the modified version of your index.yaml file with the original.
7. Run "appcfg.py update_indexes your_app_dir/"
--- end server output ---
Your app was updated, but there was an error updating your indexes. Please retry later with appcfg.py update_indexes.
C:\google>appcfg.py vacuum_indexes blog-editor/
Fetching index definitions diff.
This index is no longer defined in your index.yaml file.
ancestor: true
kind: BlogUrlYm
properties: []
Are you sure you want to delete this index? (N/y/a): y
This index is no longer defined in your index.yaml file.
ancestor: true
kind: Blog
properties: []
Are you sure you want to delete this index? (N/y/a): y
This index is no longer defined in your index.yaml file.
ancestor: true
kind: Stock
properties: []
Are you sure you want to delete this index? (N/y/a): y
This index is no longer defined in your index.yaml file.
ancestor: true
kind: Img
properties: []
Are you sure you want to delete this index? (N/y/a): y
This index is no longer defined in your index.yaml file.
kind: Blog
properties:
- direction: desc
name: ym
Are you sure you want to delete this index? (N/y/a): y
This index is no longer defined in your index.yaml file.
ancestor: true
kind: Timeline
properties: []
Are you sure you want to delete this index? (N/y/a): y
Deleting selected index definitions.
C:\google>appcfg.py update_indexes blog-editor/
Uploading index definitions.
2008年12月16日火曜日
ASSETS / 納入商品 Force.com
会社が販売する品目が商品であるのに対し、
2008年12月11日木曜日
cloud to cloud
Error: Method Not Allowed
The request method GETis inappropriate for the URL /login.
Force.com for Google App Engine
2008年12月10日水曜日
Force.com for Google App Engine 日本語
正しく登録できなかったが、
static/create_contract.py に #!-*- coding:utf-8 -*- を追加し
static/create_contract_input.html に以下を追加することで
<meta equiv="Content-Type" content="text/html; charset=utf-8">
登録することができた。
Enter your credentials:
Found 1 accounts:
Blog-Editor [View Info]
Name: Blog-Editor
ID: 0018000000MwqAqAAJ
Phone: 123456789
Web Site:
Enter your credentials:
Force.com for Google App Engine
Salesforce.com announces Force.com for App Engine
セールスフォース、「Google App Engine」と連携を可能に
クラウド・コンピューティング分野での提携を拡大
(2008年12月09日)
http://googleappengine.blogspot.com/2008/12/salesforcecom-announces-forcecom-for.html
http://developer.force.com/appengine
http://code.google.com/p/force-app-engine/downloads/list
3. Start Application
Overview
This toolkit enables developers of Google AppEngine to make calls to the Force.com web services API. The form of the toolkit is a python module code-named "BeatBox". Within this module is the main PythonClient class that has methods that coorespond to each web service api call.
Below are links to the samples that come with this toolkit. For more information, visit the Force.com Toolkit for Google AppEngine page at the Developer Force website.
Samples:
- Simple Login - Illustrates a simple login to Force.com from a Google AppEngine page
- Account Lookup - Illustrates querying data from Force.com
- Create Contact - Illustrates inserting data into Force.com
- Unit Test - Test the basics of the library, including query, create, update and delete from Force.com using the SOAP API
Enter your Force.com credentials:
Login Failed
Your login failed. Please check your username and password as well as your IP range restrictions. Error details:
Error Code: LOGIN_MUST_USE_SECURITY_TOKEN
Error Text: LOGIN_MUST_USE_SECURITY_TOKEN: ユーザ名、パスワード、セキュリティトークンが無効か、ユーザがロックされています。新しい場所からログインしていますか? 貴社の信頼済みネットワーク外からデスクトップクライアントまたは API 経由で Salesforce へアクセスする場合、パスワードにセキュリティトークンを追加してログインする必要があります。新しいセキュリティトークンは、Salesforce (http://www.salesforce.com/jp/) にログインし、[設定] | [私の個人情報] | [セキュリティトークンのリセット] をクリックして入手します。
Login Succeeded
Your login was successful. Below are your session details:
UserId: 005800xxxxxxxx
Server URL: https://na6-api.salesforce.com/services/Soap/u/14.0/511700D800000xxxx
Session Id: 511700D80000000M5IC!ARoAQAnStyOYcjTGD70Ct3cWG2UFx3NdKvA
2008年12月8日月曜日
image drag and drop and tipmage
Query UI Draggablesで簡単ドラッグドロップ
src="/javascript/jquery/jquery-1.2.6.min.js"
src="/javascript/Tipmage-1.0.js"
src="/javascript/jquery/jquery.dimensions.js"
src="/javascript/jquery/ui.mouse.js"
src="/javascript/jquery/ui.draggable.js"
src="/javascript/jquery/ui.draggable.ext.js"
http://www.museum-in-cloud.com/index.php?id=1001&option=tipmage&Itemid=1000
http://urlencode.net/result.cgi
2008年12月3日水曜日
2008年12月2日火曜日
urlfetch 403 Error
2008年11月27日木曜日
Picasa Web Albums Data API
http://code.google.com/apis/picasaweb/developers_guide_protocol.html
アルバムIDの取得
url = "http://picasaweb.google.com/data/feed/api/user/UserName"
result = urlfetch.fetch(url)
dom = minidom.parseString(result.content)
NS = 'http://search.yahoo.com/mrss/'
a = range(0,len(dom.getElementsByTagName('title')) )
for x in a:
title = dom.getElementsByTagName('title')[x].firstChild.data
id = dom.getElementsByTagName('id')[x].firstChild.data
2008年11月15日土曜日
ReferenceProperty failed to be resolved
Traceback (most recent call last):
File "/base/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 499, in __call__
handler.get(*groups)
File "/base/data/home/apps/blog-reader/1.329303600108062391/imgurl.py", line 226, in get
ImgList = imgurl_get_cache(site,server,title_lang)
File "/base/data/home/apps/blog-reader/1.329303600108062391/imgurl.py", line 308, in imgurl_get_cache
rssItems += "
File "/base/python_lib/versions/1/google/appengine/ext/db/__init__.py", line 2421, in __get__
raise Error('ReferenceProperty failed to be resolved')
Error: ReferenceProperty failed to be resolved
2008年11月13日木曜日
multipart/form-data
http://mtamaki.cocolog-nifty.com/blog/2006/05/pythonmultipart_e57f.html
POSTとMultipart
http://blog.tonic-water.com/2008/07/postmultipart.html
ClientForm
http://wwwsearch.sourceforge.net/ClientForm/
Python PILで携帯向け著作権付き画像変換
http://makunouchi.jp/zope3/3496598985
2008年11月12日水曜日
it's not found as __builtin__.instancemethod
要観察
File "/base/data/home/apps/blog-editor/1.1280/hw_blog.py", line 1073, in get_blog_menu
if not memcache.add("blogurls", blogurls, 60*60*24*30):
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 557, in add
return self._set_with_policy(MemcacheSetRequest.ADD, key, value, time=time)
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 602, in _set_with_policy
stored_value, flags = _validate_encode_value(value, self._do_pickle)
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 170, in _validate_encode_value
stored_value = do_pickle(value)
File "/base/python_lib/versions/1/google/appengine/api/memcache/__init__.py", line 274, in DoPickle
self._pickler_instance.dump(value)
File "/base/python_dist/lib/python2.5/pickle.py", line 218, in dump
self.save(obj)
File "/base/python_dist/lib/python2.5/pickle.py", line 325, in save
self.save_reduce(obj=obj, *rv)
File "/base/python_dist/lib/python2.5/pickle.py", line 413, in save_reduce
save(state)
File "/base/python_dist/lib/python2.5/pickle.py", line 280, in save
f(self, obj) # Call unbound method with explicit self
File "/base/python_dist/lib/python2.5/pickle.py", line 643, in save_dict
self._batch_setitems(obj.iteritems())
File "/base/python_dist/lib/python2.5/pickle.py", line 675, in _batch_setitems
save(v)
File "/base/python_dist/lib/python2.5/pickle.py", line 325, in save
self.save_reduce(obj=obj, *rv)
File "/base/python_dist/lib/python2.5/pickle.py", line 390, in save_reduce
save(cls)
File "/base/python_dist/lib/python2.5/pickle.py", line 280, in save
f(self, obj) # Call unbound method with explicit self
File "/base/python_dist/lib/python2.5/pickle.py", line 742, in save_global
(obj, module, name))
PicklingError: Can't pickle
--
回復
Our memcache maintenance was completed at 10:52 PST (GMT-8). During
this period, although calls to the API did in fact return False and
None as expected, memcache API response latency increased
significantly, causing requests with heavy memcache dependence to time
out after 10 seconds due to the request timer, covered in our
documentation here: http://code.google.com/appengine/docs/python/requestsandcgi.html
We're now implementing a fix for this issue, and in the future the
memcache API will return immediately in the event of an outage. We
apologize for any inconvenince this may have caused.
Pete Koomen, App Engine Team
On Nov 12, 6:05 pm, App Engine Team
2008年11月11日火曜日
2008年11月5日水曜日
datastore_errors.BadArgumentError:_app must not be empty.
using the scheme described in another post [1]) started failing with
the following stack trace:
I added the following in my test setup:
os.environ['APPLICATION_ID'] = APP_ID
http://groups.google.com/group/google-appengine/browse_thread/thread/d20dd715e4950970/560fdd931758cb38?lnk=gst&q=+_app+must+not+be+empty#560fdd931758cb38
こうしたものもある。
http://shell.appspot.com/
http://code.google.com/p/google-app-engine-samples/source/browse/trunk/shell/shell.py
2008年11月3日月曜日
2008年10月31日金曜日
2008年10月27日月曜日
Thumbnail Generation
http://www.zubrag.com/scripts/thumbnail-generator.php
http://localhost/test/webthumb.php?url=http://www.yahoo.co.jp
Thumbnail Generation Error. Thumbnail not created.
http://www.zubrag.com/forum/index.php/topic,33.0.html
C:\xampp\htdocs\test>IECapt.exe http://www.yahoo.com test.png
C:\xampp\htdocs\thumbnail
IECapt.exe
image.class.php
webthumb.php
//$thumbnails_folder = 'Z:/home/localhost/www/thumb/cache/';
$thumbnails_folder = 'C:/work/';
from PIL import Image, ImageDraw, ImageFont
font = ImageFont.truetype('/usr/local/grass5/fonts/ipagp.ttf',25, encoding='unic')
image = Image.new('RGBA', (100, 100))
draw = ImageDraw.Draw(image)
draw.text((0, 0), u'テスト', font=font, fill='#000000')
image.save('hoge.png', 'PNG')
http://humming.via-kitchen.com/2007/10/14/string-2-image-using-pil/
PIL Tutorial: How to Create a Button Generator
http://nadiana.com/pil-tutorial-how-create-button-generator
2008年10月13日月曜日
Cooliris と GAE 連携
http://www.cooliris.com/
http://developer.cooliris.com/
crossdomain.xml の設定が必要
http://groups.google.com/group/google-appengine/browse_thread/thread/f064730ead93eedc/4876f0b321b580d0?show_docid=4876f0b321b580d0&fwc=1
ブラウザのキャッシュをクリアしないと、crossdomain エラーが止まらなかった。
ローカルでのテスト
swf ファイルの保存
http://www.browsertools.net/Flash-Saving-Plugin/index.html
ローカルファイルシステムの SWF および信頼されているローカル SWF ファイルのみがローカルリソースにアクセスできます
C:\WINDOWS\system32\Macromed\Flash\FlashPlayerTrust\AcrobatConnect.cfg
に swf の位置を追加
C:\xampp\htdocs\rss\cooliris.swf
2008年10月4日土曜日
Primary Key と Key_name ~MySQLのデータをGAEへ
図のData Viewer の画面であると新たに追加した Model が List に表示されるまでに少しタイムラグがあるため、作業中の動作確認は Logs の画面を監視して行なった。
今回、30個程度のテーブルを対象に作業を行なったが、RDBMS のキー項目とGoogle App Engine の Key_name の対応は以下のようになった。
Key_name は設定したが、parent は設定しなかった。
col = ""
bid = ""
cid = ""
content_id = ""
session_id = ""
menuid = ""
client_id = ""
time = ""
for r in rr:
if r.column_name == 'id' or r.column_name == 'cid':
key_name = 'id' + self.request.get(r.column_name)
j = clazz(key_name = key_name)
if r.column_name == 'cid' : cid = self.request.get(r.column_name)
if r.column_name == 'content_id': content_id = self.request.get(r.column_name)
if r.column_name == 'bid' : bid = self.request.get(r.column_name)
if r.column_name == 'time' : time = self.request.get(r.column_name)
if r.column_name == 'session_id': session_id = self.request.get(r.column_name)
if r.column_name == 'menuid' : menuid = self.request.get(r.column_name)
if r.column_name == 'client_id' : client_id = self.request.get(r.column_name)
if menuid and client_id:
key_name = 'id' + menuid + client_id
j = clazz(key_name = key_name)
if session_id and time:
key_name = 'id' + time + session_id
j = clazz(key_name = key_name)
if content_id:
key_name = 'id' + content_id
j = clazz(key_name = key_name)
if cid and bid:
key_name = 'id' + bid + cid
j = clazz(key_name = key_name)
2008年10月3日金曜日
トランザクションとデータ確認2 ~MySQLのデータをGAEへ
MySQL からColud へのデータの POST に較べれは、Cloud の一部のキーとなる項目データを取得して、 MySQLに格納するようにするのは工数は少なそうなので、Download 側も作成することに。
Python(Cloud , Google App Engine )
件数とキー項目(key_name)の表示
if self.request.get('cmd') == "columns":
rr = db.GqlQuery("select * from Information_schema_columns")
for r in rr:
self.response.out.write( r.key().name()+"<br>")
self.response.out.write( "count(*) = " + str(rr.count() ))
PHP(MySQL)
Cloud にアクセスし、リストされたデータを取得し、MySQL用のinsert文のSQL を作成し、表示(行末の余計なデータは手動削除)
$req =& new HTTP_Request("http://xxxx/sign?cmd=columns");
if (!PEAR::isError($req->sendRequest())) {
$imgList = $req->getResponseBody();
}
$dd = explode("<br>", $imgList) ;
$sql = "insert into `gae_columns` ( `column` ) values " ;
foreach ($dd as $d) {
$sql_values .= "( '".$d."' )," ;
}
MySQL に gae_column というテーブルを作成し、これに Cloud からの一覧データを挿入。
・MySQL に取得後のデータの確認用SQL
- 一覧
SELECT concat(table_name,'.',column_name) FROM
information_schema.columns i ,
joomlaj.gae_columns g
where i.table_schema ='joomlaj'
and concat('joomlaj_',table_name,'.',column_name) = g.column
- 不足分のリスト
SELECT concat(table_name,'.',column_name)
FROM information_schema.columns i
where i.table_schema ='joomlaj'
and concat('joomlaj_',table_name,'.',column_name) not in
(select g.column from joomlaj.gae_columns g)
やはりこうした作業は RDBMS が格段に優れる。
トランザクションとデータ確認1 ~MySQLのデータをGAEへ
5回程度のLoop とした。SQL の offset を追加しながら、間隔をあけて実行。
SELECT * FROM information_schema.columns where table_schema ='joomlaj' order by table_name, ordinal_position limit 0,5
SELECT * FROM information_schema.columns where table_schema ='joomlaj' order by table_name, ordinal_position limit 5,5
require_once "HTTP/Request.php";
$req =& new HTTP_Request($post_url);
$req->setMethod(HTTP_REQUEST_METHOD_POST);
・・・
$database->setQuery( $sql2 );
$rows = @$database->loadAssocList();
foreach($fields[$table] as $field=>$type) { ?>
eval($get_fld_value);
$req->addPostData(strtolower($field), $value);
$request .= '&table='.$table ;
$request .= '&table_name='.$table_name ;
$req->addPostData('table', $table);
$req->addPostData('table_name', $table_name);
if (!PEAR::isError($req->sendRequest())) {
$response1 = $req->getResponseBody();
} else {
$response1 = "";
}
POST されたものを受ける、Python(Google App Engine の Cloud )側での概要はこちら。
*1 PHP の fsockopen ではGAEのSDKでは動作しても cloud への POST はうまくかないようなので注意
2008年10月2日木曜日
Dynamic Datastore MySQLのデータをGAEへ
Datastore 側の key_name にはスキーマ、テーブル、カラム名を結合したものを設定した。
key = information_schema_columns.table_schema + "_"
key += information_schema_columns.table_name+ "."
key += information_schema_columns.column_name
Information_schema_columns.get_or_insert(key,
table_catalog = self.request.get('table_catalog'),
table_schema = self.request.get('table_schema'),
table_name = self.request.get('table_name'),
column_name = self.request.get('column_name'),
ordinal_position = ordinal_position,
column_default = column_default,
is_nullable = self.request.get('is_nullable'),
data_type = self.request.get('data_type'),
character_maximum_length = character_maximum_length,
character_octet_length = character_octet_length,
numeric_precision = numeric_precision,
numeric_scale = numeric_scale,
character_set_name = self.request.get('character_set_name'),
collation_name = self.request.get('collation_name'),
column_type = self.request.get('column_type'),
column_key = self.request.get('column_key') ,
extra = self.request.get('extra'),
privileges = self.request.get('privileges'),
column_comment = self.request.get('column_comment'))
けれども、この情報を利用してデータを転送する汎用的なものを作成しなければならない。
RDBMSには動的SQLという仕組みがあるが、 Datastore ではどのように対応したらいいのであろうか。
「Pythonでリフレクションする」*1 などと参考にいろいろと試行錯誤、ようやくそれらしいものができた。
clazz = globals()[cls.capitalize()]
obj = clazz()
setattr
Joomla! では id あるいは cid 列を設定しているようなので、まずはこれらを利用することに。
def post_mysql_data(self,cls):
clazz = globals()[cls.capitalize()]
obj = clazz()
table = cls
rr = db.GqlQuery("select * from Information_schema_columns where table_name = :1", table )
col = ""
for r in rr:
if r.column_name == 'id' or r.column_name == 'cid':
column_value = self.request.get(r.column_name)
key_name = 'id' + column_value
j = clazz(key_name = key_name)
if j:
for r in rr:
column_value = self.request.get(r.column_name)
if r.data_type == 'varchar' or r.data_type == 'text' or r.data_type == 'longtext' :
if column_value : setattr(j,r.column_name,column_value)
if r.data_type == 'bigint' or r.data_type == 'tinyint' or r.data_type == 'int' :
if column_value : setattr(j,r.column_name,int(column_value))
if r.data_type == 'datetime':
if column_value :
if column_value == '0000-00-00 00:00:00':column_value = '1901-01-01 00:00:00'
column_value = datetime.datetime.strptime(column_value,'%Y-%m-%d %H:%M:%S')
setattr(j,r.column_name,column_value)
col = j.put()
*1 shisashiの開発日記 http://shisashi.blogspot.com/
information.schema.columns MySQLのデータをGAEへ
を使うと、 Joomla! というCMSの Administration 画面で phpMyAdmin ライクの操作を行なうことができる。
MySQLのデータをGAEへ
if ($data_type == "bigint" ) { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "tinyint") { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "int" ) { $datastore_type = " = db.IntegerProperty()" ;}
if ($data_type == "varchar") { $datastore_type = " = db.StringProperty()" ; }
if ($data_type == "text") { $datastore_type = " = db.TextProperty()" ; }
if ($data_type == "longtext"){ $datastore_type = " = db.TextProperty()" ; }
if ($data_type == "datetime"){ $datastore_type = " = db.DateTimeProperty()" ; }
2008年10月1日水曜日
fsock でcloud にPOSTしても値が届かない
local の Google App Engine の SDK 環境では動作しても、本番環境の Cloud では
501 エラーなども発生。
チェックが厳しいためか。
http://code.google.com/p/gears/wiki/ContentRangePostProposal
結局 PEAR を利用したところ、無事 cloud に対してでも POST できるようになった。
http://pear.php.net/manual/ja/package.http.http-request.headers.php
2008年9月22日月曜日
Joomla
joomlaj\installation_\sql\mysql\sample_data_sql
INSERT INTO `#__menu_types` VALUES
(2, 'usermenu', 'User Menu', 'A Menu for logged in Users'),
(3, 'topmenu', 'Top Menu', 'Top level navigation'),
(4, 'othermenu', 'Resources', 'Additional links'),
(5, 'ExamplePages', 'Example Pages', 'Example Pages'),
(6, 'keyconcepts', 'Key Concepts', 'This describes some critical information for new Users.');
/language/ja-JP/ja-JP.ini の以下を変更(結局スペースを追加)
DATE_FORMAT_LC2=%Y年 %B %d日(%A) %H:%M
#DATE_FORMAT_LC2=%Y年%B%d日(%A) %H:%M
無料Joomla!テンプレー http://www.joomlashack.jp/content/view/4/9/
Joomla ジャパン http://www.joomla.jp/
Joomla Template Tutorial http://dev.joomla.org/content/view/1136/79/
Joomla! 1.5 変更部分
・ メニューの構築手順
外部ファイルの取り込みがエクステンションに一元化
・ テンプレートではtemplateDetails.xml の役割
モジュールポディションの設定、テンプレートパラメータの設定が可能
テンプレート側にポディション
・ 特定のメニューから呼び出されたページに対し、テンプレートを指定することができる
・ Joomla! 1.5.3 でタイトルタグにサイト名を表示させるための変更
・phpフレームワーク・オブジェクト指向入門 http://phpc2.seesaa.net/
PHP5の新機能(クラス関係) http://www.atmarkit.co.jp/fcoding/articles/php5/02/php502a.html
・引数の値渡しと参照渡し http://ww7.tiki.ne.jp/~inabah/php/004_002.htm
Home Developer Manual 11. API Reference [REVIEW] database->loadAssocList
Tutorial:Developing a Model-View-Controller Component - Part 1
2008年9月19日金曜日
Uploading index definitions Error
Issue 287: | Explosion with >100 indexes |
To vacuum your indexes:
1. Create a backup of your index.yaml specification
2. Remove the definitions of the indexes in Error from your index.yaml file
3. Run appcfg.py vacuum_indexes your_app_dir/
4. Replace the modified version of your index.yaml file with the original
5. Run appcfg.py update your_app_dir/
appcfg.py vacuum_indexes your_app_dir/
にて今度は Y にて削除した。
いくつも削除したため、ダッシュボードでみると index の delete のタスクが走りだした。このタスク中に appcfg.py update xxxx/ すると
Server Error (500) A server error has occured.
となる。しばらく、時間をおいたところ無事 update できたが、その直後から今度はindex 作成のタスクがいくつも走りだした。
http://code.google.com/appengine/docs/datastore/queriesandindexes.html#Big_Entities_and_Exploding_Indexes
To handle "Error" indexes, first remove them from your index.yaml file and run appcfg.py vacuum_indexes. Then, either reformulate the index definition and corresponding queries or remove the entities that are causing the index to "explode." Finally, add the index back to index.yaml and run appcfg.py update_indexes.
2008年9月13日土曜日
Google Visualization API その2
データとして与える場合 123.*100/100 のように一度 乗算して除算しないとなぜかうまくいか
なかった。 ( javascript を理解していない? ためか これには苦労した)
2008年9月12日金曜日
Google Visualization API
2008年9月8日月曜日
Google Chart API で日本語
2008年9月7日日曜日
Timeout Error
TemplateSyntaxError: Caught an exception while rendering:
テンプレートが重いのが問題かと 表示内容をけづっていったところ
動作したり、しなかったり。
File "/base/python_lib/versions/1/google/appengine/api/datastore.py", line 1627, in _ToDatastoreError同様の現象の報告もあり、様子をみることに。
raise errors[err.application_error](err.error_detail)
Timeout
http://groups.google.com/group/google-appengine/browse_thread/thread/53e7e0a34f3bec89/37b2a5a033ee0ac0?hl=en&lnk=gst&q=timeout+error#37b2a5a033ee0ac0
つい先日も login: admin の設定の URL ではログインできなかったが、翌日は復活していた。
2008年9月5日金曜日
Property XXX must be a str or unicode instance, not a tuple
aa = Img( p1 = val )
aa.put()
不要なカンマがある場合などでもこのエラーとなる
BadValueError: Property p1 must be a str or unicode instance, not a tuple
2008年9月3日水曜日
トランザクション エラー Nested transactions are not supported.
作成しようとするとエラーとなる。
File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore.py",
line 1386, in RunInTransaction'Nested transactions are not supported.')
BadRequestError: Nested transactions are not supported.
2.動作確認
First up is batch writes. You can now include entities in different entity groups in a single db.put() or db.delete() call. Entity modifications are only atomic within each entity group, but a single call that spans entity groups will be more efficient than a call for each group, which was required before.
以下は SDK だと Cannot operate on different entity groups in a transaction:
となるが Cloud では動作した。
class Dummy2(db.Model):
d1 = db.StringProperty()
class Dummy(db.Model):
d1 = db.StringProperty()
def tran():
d2 = Dummy2(d1 = "aaab")
d1 = Dummy(d1 = "aaab")
d1.put()
d2.put()
tran()
3. その他
トランザクションの中で検索は実行できない。
Can't query inside a transaction
2008年9月1日月曜日
YouTube API
に従い進めた。
Developer Key の取得の際は自分でどのように利用するか簡単に記述。
(どこかから値を持ってきて登録するのではない)
けれども、検索するだけであれば
self.developer_key = 'ADD YOUR DEVELOPER KEY HERE'この部分は不要だった。
チュートリアルのSourceは以下にあるが、これらを特にダウンロードするまでの必要はなかった。
http://code.google.com/p/hello-youtube/source/browse/#svn/trunk/03_hello_youtube_search_query
http://code.google.com/p/hello-youtube/source/browse/#svn/trunk/04_hello_user_input
gdata 関連の設定は既に spredsheet などにアクセスするために導入してあったので
素直に検索を行なうことができた。
Youtube は検索言語の設定により、検索結果がかなり異なるので
http://code.google.com/apis/youtube/reference.html#Query_parameter_definitions
を参考に lr は追加しておいた。
query.vq = search_term
query.max_results = '5'
query.lr = 'ja'
if entry.rating:
2008年8月31日日曜日
NormalizeAndTypeCheck エラー
○ login.session.key()
× login.session
忘れた場合のエラー
keys, multiple = datastore.NormalizeAndTypeCheckKeys(keys)
File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore.py", line 117, in NormalizeAndTypeCheckK
ys
keys, multiple = NormalizeAndTypeCheck(keys, (basestring, Entity, Key))
File "C:\Program Files\Google\google_appengine\google\appengine\api\datastore.py", line 96, in NormalizeAndTypeCheck
(types, arg, typename(arg)))
adArgumentError: Expected an instance or sequence of (
2008年8月26日火曜日
mixi openid
を参考にテストしたところ
local:8080 だと動作するが Cloud (GAE に upload すると)だと以下のエラーとなる。
---
Traceback (most recent call last):
File "/base/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 499, in __call__
handler.get(*groups)
File "/base/data/home/apps/blog-editor/1.937/mixi_login.py", line 28, in get
request = consumer.begin('https://mixi.jp')
File "/base/data/home/apps/blog-editor/1.937/openid/consumer/consumer.py", line 354, in begin
'No usable OpenID services found for %s' % (user_url,), None)
DiscoveryFailure: No usable OpenID services found for https://mixi.jp
----
以下、参考
http://d.hatena.ne.jp/mitsugi-bb/20080823/1219592219#c
http://www.socialpreneur.info/ja/blog/784
http://ms76.jp/2008/08/22/mixi_openid_for_wordpress/
http://insilico.jognote.com/blog/2008/08/13/curl-%E3%81%AB-https-%E3%81%A7%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B/
---
おそらくこれが原因
Issue 407 http://code.google.com/p/
webapp.RequestHandler.redirect missing location header for long urls
2008年8月12日火曜日
spreadsheet からの GAE への upload
GAE Cloud の datastore に upload する script を作成
利用方法
- まず、spreadsheet のデータを読み込みます。
- 今回は対象は DOW の株価データで 960 レコード程度です。
- SDK 環境では一度にすべての spreadsheet のデータを読み込むことができましたが、
cloud では 100 行程度 ( 200行はエラー ) ごとに複数のシートにデータを分割 - "read" とし、シートの key と シート番号を指定
- 1 sheet 分のデータを Memcache に読み込みます。
- 今回は対象は DOW の株価データで 960 レコード程度です。
- 読み込んだデータを GAE Cloud の datastore に書き込みます。
- "put" を指定
- 100 行一度に書き込もうとするとエラーになりますので、今回の場合、20行程度ごとに
区切り、 offset をかけながら、何度かに分けて書き込み処理を行ないました。
- "put" を指定
- offset は自動的に加算するようにしましたので、[Sign Guest]を繰り返しクリック
- 1 sheet 分のデータの upload が完了したら Memcache をクリア
- 次のシート番号を指定し、同様の作業を繰り返します。
2008年8月11日月曜日
Memcache API
日本語訳 http://d.hatena.ne.jp/technohippy/20080717#1216393318
memcache.add( key, value, time=xx, min_compress_len=0)
- time 設定した有効時間(単位秒)以後は再度、検索処理を行なう
- Optional expiration time, either relative number of seconds from current time (up to 1 month), or an absolute Unix epoch time. By default, items never expire, though items may be evicted due to memory pressure. Float values will be rounded up to the nearest whole second.
- set()
- set_multi()
- get()
- get_multi()
- delete()
- delete_multi()
- add()
- replace()
- incr()
- decr()
- flush_all()
- get_stats()
ex.
{'hits': 34, 'items': 5, 'bytes': 45587, 'oldest_item_age': 1800, 'misses': 21, 'byte_hits': 946479}
2008年8月4日月曜日
Debug デバッグ
* Cloud ではログにエラー出力されるの危険
import sys
print >>sys.stderr, "xxxxxxx"
正しくは
import logging
logging.debug("xxxxxxx")
def main():
# Set the logging level in the main function
# See the section on Requests and App Caching for information on how
# App Engine reuses your request handlers when you specify a main function
logging.getLogger().setLevel(logging.DEBUG)
application = webapp.WSGIApplication([('/', MainPage),
('/sign', Guestbook)],
debug=True)
webapp.util.run_wsgi_app(application)
if __name__ = '__main__':
main()
参考
http://code.google.com/appengine/articles/logging.html
・http://code.google.com/appengine/docs/python/logging.html
・http://groups.google.com/group/google-appengine/browse_thread/thread/a67752ac402bb21e/345e203a5bdd0750?lnk=gst&q=debug+#345e203a5bdd0750
・Django Middleware で Traceback をコンソールに出力する
http://yamashita.dyndns.org/blog/django-middleware-traceback/
2008年7月23日水曜日
UnicodeEncodeError と webapp.RequestHandler
の中で
str.decode("utf-8",'ignore')
とすると
UnicodeEncodeError
となるようなのですが、
webapp.RequestHandler を介さない別のところで処理している場合、
エラーは発生していない。
UnicodeEncodeError はまだよく理解できていないところがありますが。
メモ
UnicodeEncodeError: 'ascii' codec can't encode characters in position 422-424
: ordinal not in range(128)
Unicode 文字列をバイト列に符号化 (encode) するとき, range(128) つまり 0 から 127 までの文字コードしか扱えない 'ascii' エンコーディングが使われ,日本語文字に対して例外 UnicodeEncodeError が起こったもの
http://www.okisoft.co.jp/esc/cygwin-15a.html
webapp を調べたよ (前編) - Google App Engine
http://d.hatena.ne.jp/hamatsu1974/20080422/1208802967
2008年7月17日木曜日
DeadlineExceededError
対応例
http://stage.vambenepe.com/archives/category/implementation
結果 google/appengine/runtime/apiproxy.py を参考に
from google.appengine import runtime
from google.appengine.runtime import apiproxy_errors
from google3.apphosting.runtime import _apphosting_runtime___python__apiproxy
これらを import して対応
except runtime.DeadlineExceededError:
File "/base/python_lib/versions/1/google/appengine/runtime/apiproxy.py", line 161, in Waitだけでなく CancelleError というものもある。
rpc_completed = _apphosting_runtime___python__apiproxy.Wait(self)
DeadlineExceededError
File "/base/python_lib/versions/1/google/appengine/runtime/apiproxy.py", line 189, in CheckSuccess
raise self.exception
CancelledError: The API call datastore_v3.Count() was explicitly cancelled.
2008年7月8日火曜日
Key Limitations: 500 bytes
parent を設定すると、親の key が自分の key の先頭に付く。
parent が parent を持っていると、孫の key は長くなる。
限界が 500 byte
従って、当然、 親を設定し、さらにこれに親が設定されていれば
ancestor is により祖先を検索条件に指定することができる。
b = db.GqlQuery("select * from Blog where ancestor is :1 ", granpa.key())
Tools for storing data: Keys
* Key corresponds to the Bigtable row for an Entity
* Bigtable accessible as a distributed hashtable
* Get() by Key: Very fast! No scanning, just copying data
* Limitations:
o Only one ID or key_name per Entity
o Cannot change ID or key_name later
o 500 bytes
2008年7月7日月曜日
Building Scalable Web Applications/Building a Blog
from google.appengine.ext import db
class BlogIndex(db.Model):
max_index = db.IntegerProperty(required=True,default=0)
class BlogEntry(db.Model):
index = db.IntegerProperty(required=True)
title = db.StringProperty(required=True)
body = db.TextProperty(required=True)
def post_entry(blogname, title, body):
def txn():
blog_index = BlogIndex.get_by_key_name(blogname)
if blog_index is None:
blog_index = BlogIndex(key_name=blogname)
new_index = blog_index.max_index
blog_index.max_index += 1
blog_index.put()
new_entry = BlogEntry(key_name=blogname + str(new_index),parent=blog_index, index=new_index,title=title, body=body)
new_entry.put()
db.run_in_transaction(txn)
def get_entry(blogname, index):
entry = BlogEntry.get_by_key_name(blogname + str(index),parent=Key.from_path('BlogIndex',blogname))
return entry
def get_entries(start_index):
extra = None
if start_index is None:
entries = BlogEntry.gql(
'ORDER BY index DESC').fetch(POSTS_PER_PAGE + 1)
else:
start_index = int(start_index)
entries = BlogEntry.gql(
'WHERE index <= :1 ORDER BY index DESC', start_index).fetch(POSTS_PER_PAGE + 1) if len(entries) > POSTS_PER_PAGE:
extra = entries[-1]
entries = entries[:POSTS_PER_PAGE]
return entries, extra
Building Scalable Web Applications から
Oracle などで Create sequence するように Counter 専用のModel を作成して、
increment("xxxx")
するようにしたほうがよいのか。 Writes are expensive!
- Datastore is transactional: writes require disk access
- Disk access means disk seeks
- Rule of thumb: 10ms for a disk seek
- Simple math:
- 1s / 10ms = 100 seeks/sec maximum
- Depends on:
- The size and shape of your data
- Doing work in batches (batch puts and gets)
Reads are cheap!
- Reads do not need to be transactional, just consistent
- Data is read from disk once, then it's easily cached
- All subsequent reads come straight from memory
- Rule of thumb: 250usec for 1MB of data from memory
- Simple math:
- 1s / 250usec = 4GB/sec maximum
- For a 1MB entity, that's 4000 fetches/sec
Tools for storing data: Entities
- Fundamental storage type in App Engine
- Set of property name/value pairs
- Most properties indexed and efficient to query
- Other large properties not indexed (Blobs, Text)
- Think of it as an object store, not relational
- Kinds are like classes
- Entities are like object instances
- Relationship between Entities using Keys
- Reference properties
- One to many, many to many
Tools for storing data: Entity groups 2
Hierarchical
- Each Entity may have a parent
- A "root" node defines an Entity group
- Hierarchy of child Entities can go many levels deep
- Watch out! Serialized writes for all children of the root
Datastore scales wide
- Each Entity group has serialized writes
- No limit to the number of Entity groups to use in parallel
- Think of it as many independent hierarchies of data
class CounterConfig(db.Model):
name = db.StringProperty(required=True)
num_shards = db.IntegerProperty(required=True,default=1)
class Counter(db.Model):
name = db.StringProperty(required=True)
count = db.IntegerProperty(required=True,default=0)
def get_count(name):
total = 0
for counter in Counter.gql('WHERE name = :1', name):
total += counter.count
return total
def increment(name):
config = CounterConfig.get_or_insert(name,name=name)
def txn():
index = random.randint(0, config.num_shards - 1)
shard_name = name + str(index)
counter = Counter.get_by_key_name(shard_name)
if counter is None:
counter = Counter(key_name=shard_name, name=name)
counter.count += 1
counter.put()
db.run_in_transaction(txn)
increment("test")
print get_count("test")
def get_count(name):
total = memcache.get(name)
if total is None:
total = 0
for counter in Counter.gql('WHERE name = :1', name):
total += counter.count
memcache.add(name, str(total), 60)
return total
def increment(name):
config = CounterConfig.get_or_insert(name,name=name)
def txn():
index = random.randint(0, config.num_shards - 1)
shard_name = name + str(index)
counter = Counter.get_by_key_name(shard_name)
if counter is None:
counter = Counter(key_name=shard_name,name=name)
counter.count += 1
counter.put()
db.run_in_transaction(txn)
memcache.incr(name)
http://sites.google.com/site/io/building-scalable-web-applications-with-google-app-engine
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: ...