2011年5月25日水曜日

GAE 多対多モデルのデータ削除について

Google app engin の datastoreで多対多を下記ページなどを参考につくりました。
http://code.google.com/intl/ja/appengine/articles/modeling.html

グループとユーザの関係を多対多で構築しています。models.pyの内容は下記になります。
※私は、GAEをPythonとDjango(パッチ)でつくっています。

class Users(db.Model):
    name= db.StringProperty()
    group=db.ListProperty(db.Key)

class Groups(db.Model):
    name=db.StringProperty()
    owner=db.IntergerProperty()

グループのオーナーがグループを削除する為のスクリプトを書こうと思っているのですが、グループを削除する際に、参加しているユーザーのgroupから、削除するグループのkeyを削除する必要があります。これについて最も効率的な方法を教えていただけますでしょうか。

GAEはデータの変更・削除に結構時間がかかります。仮に数万人所属しているグループがあったとし、このグループをオーナーが削除する場合、グループに所属しているユーザーのgroupに全てアクセスし、該当グループのkeyを削除する操作は非効率(30秒を超える可能性が十分あるの)ではないかと思っています。

宜しくお願いします。

投稿日時 - 2011-05-22 17:11:48

と、OkWebで質問した。
下記を回答いただきました。

GAEは、ちょっと特殊ですからね……。あんまりいい方法とは思えないのですが、削除するときは、単純にGroupsのownerをクリアするだけにしてはどうでしょうか(ownerが、グループの作者を示すデータですよね?)検索時に、グループのownerがないときは「そのグループは抹消済み」として表示しないようにするなど対処しておくわけですね。

そして、それとは別に、CRONなどを使って定期的にownerが空のGroupsを検索し、そのGroupsが保管されているUsersを少しずつ(一度に最大1000ずつとか)取り出してはgroupを更新していく、というのはどうでしょうか。いわば、ガベージコレクションをCRONで作るわけです。あるいは、最悪、手動で定期的に削除してもよいでしょうし……。

残念だけどそういうことなのか。

2011年5月22日日曜日

GAE Keyを文字列で取得した場合にオブジェクトを取り出す方法

将来の俺ならこのタイトルでわかるだろう。

GAEのmodelにはkeyがあります。これは各エンティティに固有のキーです。これはKeyオブジェクトのインスタンスですが、文字列に変更できます。よって、サイト上でこの文字列をやり取りし、後程このkey文字列をもとにエンティティを取得することができます。db.Key(文字列)によって、文字列はKeyオブジェクトのインスタンスに変わります。後は、db.get(Keyインスタンス)とすることで、エンティティが取り出せます。

obj = MyModel(name="Foo")
self.response.write('%s' % (str(obj.key()), obj.name()))

# ...

key_name = self.request.get('key')
obj = db.get(db.Key(key_name))

データの作成、取得、削除 - キーを使用したエンティティの取得

jQuery 将来的にも適用されるイベントハンドラの登録

基本的にjavascriptが読み込まれた時点で存在しない要素には、イベントハンドラは適用されない。
将来発生する要素にもイベントハンドラを適用したい場合は、liveを使う。

live(type, fn)

jQuery日本語リファレンス - live(type, fn)

登録されたイベントは、現在および将来的にも、セレクタにマッチする全ての要素に適用されます。
カスタムイベントに対してbindすることも可能です。

この関数で指定できるイベントは、次の通りです:
click, dblclick, mousedown, mouseup, mousemove, mouseover, mouseout, keydown, keypress, keyup

現時点ではサポートしていないイベントは、次の通りです:
blur, focus, mouseenter, mouseleave, change, submit

bindとほぼ同様の関数ですが、ハンドラ登録時にマッチする要素だけでなく、永続的にイベント発生時点でマッチする要素に反応する点が異なります。

サンプル
<script type="text/javascript">
$(function(){
 $('.gp_del').live("click", function(){del_group(this.name);});
});
</script>