2009年8月10日 星期一

減輕資料查詢、更新的負擔

在 Google App Engine 上開發應用程式,很多人會面臨到使用額度(Quota)的問題,所以開發者在將應用程式上線後,必須不斷觀察應用程式的存取狀況,以便隨時調整應用程式,避免某一項使用額度過份衝高。

這篇文章要介紹的是--儘可能地減少資料查詢、更新的動作,因為 Datastore API 的呼叫次數有限制,而且一個 request 的處理時間也有 30 秒的限制,如果在操作資料時沒有注意到一些細節,可能就會碰到問題。

平行讀取、更新或刪除 data entities


在「避免資料寫入衝突」這篇文章中,提到可以使用 App Engine 所提供的 memcache API 來作資料快取,這樣也是一種減少呼叫 Datastore API 的策略。

除此之外,善加利用每個 data entity 的 key 也可以達到減少呼叫 Datastore API 的目標。例如以下這段程式碼:
...
# 修改許多 data entity
for product in products:
product.price = product.price * 1.1
product.put()
...

在這個例子中,products 中有多少個 entities,就會呼叫多少次 put(),但若是將上述的程式碼修改為:
...
from google.appengine.ext import db
# 修改許多 data entity
for product in products:
product.price = product.price * 1.1
db.put(products)

由於 db.put() 函式支援 list 資料型態的參數,所以這樣的作法僅會算作一次 Datastore API 的呼叫,比起上述的方式大大節省了 Datastore API 的呼叫次數。

讀取資料時也是以此類推,若原本的程式為:
...
products = []
# keys 為一個 key list
for key in keys:
products.append(db.get(key))

也可以改寫成:
...
from google.appengine.ext import db
# keys 為一個 key list
products = db.get(keys)

同理可證,若要同時刪除許多 entities,也可以使用 db.delete

有效率地使用 GQL


另外,若是要使用 GqlQuery 作資料查詢時,若是只需要取出 entities 的 key 值,在 GQL 查詢語句中僅需取出 __key__ 欄位即可:
...
from google.appengine.ext import db

product_keys = db.GqlQuery('SELECT __key__ FROM Product WHERE title = :title', title='...')
# 或是 product_keys = Product.gql('WHERE title = :title', title='...', keys_only=True)

如此一來,讀取的時間就會比讀取全部的欄位還要快許多(如果資料量夠多的話...)

另外,若是查詢語句會重複使用,可以將該語句建立成一個 GqlQuery 物件後,再利用 bind() 方法重新利用該查詢語句。例如本來的程式碼可能是:
...
from google.appengine.ext import db

conditions = [['x', 'y'], ['1', '2'], .....]
for cond in conditions:
query = db.GqlQuery('SELECT * FROM Foo WHERE first = :first, second = :second', first=cond[0], second=cond[1])
....

如此一來,迴圈每執行一次就會建立一個 GqlQuery 物件,資料查詢會變得很沒有效率,如果碰到這樣的情況,程式碼應該改寫為:
...
from google.appengine.ext import db

conditions = [['x', 'y'], ['1', '2'], .....]
prepared_query = db.GqlQuery('SELECT * FROM Foo WHERE first = :first, second = :second')
for cond in conditions:
query = prepared_query.bind(first=cond[0], second=cond[1])
....

如此便能重複利用 GqlQuery 這個物件了。

2009年8月5日 星期三

使用 Eclipse + PyDev 開發 Google App Engine 專案

在 Windows 上開發應用程式,大多數的開發者會藉著使用 IDE 來輔助開發,簡化一些設定、啟動或測試等步驟。而在 Windows 上若要開發 Google App Engine 的應用程式,使用 Eclipse 作為 IDE,並且搭配 PyDev 這個 Eclipse 的 plugin,會簡化許多開發的設定,尤其是最新的 PyDev 甚至還直接支援了 Google App Engine 專案呢!以下就為各位做個簡單的介紹。

安裝及設定


在開始之前,先確定您的 Windows 環境已經安裝了 Java SDK (JDK) 以及 Python (目前 Google App Engine 僅支援 Python 2.5.x) 。Java 是為了執行 Eclipse,而 Python 當然就是為了用來執行 Google App Engine 的專案囉。

首先,到 Eclipse 的官方網站下載 Eclipse Classic 3.5.0



下載回來後,將 zip 檔案解壓縮,執行 eclipse 目錄中的 eclipse.exe 便可以開啟 Eclipse:



開啟 Eclipse 之後,首先將環境的設定作點修改,從功能表列的 Window » Preferences 進入設定畫面,首先設定用空白取代 tab 字元,因為 Python 對於程式碼的縮排有嚴格的一致性,所以為了避免不必要的煩惱,在 General » Editor » Text Editors 的設定中,將 tab 取代為 4 個空白字元



除此之外,也將由 Eclipse 所建立的專案,調整成預設使用 UTF-8 作為字元編碼,以及使用 UNIX 換行字元




為了讓 Eclipse 能夠作為開發 Python 專案的 IDE,此時還需要安裝 PyDev 這個 plugin,可以從PyDev 的官方網站上看到安裝 URL(如:http://nightly.aptana.com/pydev/site.xml),將這個 URL 複製下來,回到 Eclipse,到功能表列的 Help » Install New Software...,將剛才複製的 URL 貼在 Work with: 的文字框中,並按下 Add 按鈕:



接著就是勾選 PyDev 然後將它安裝完成,安裝完畢後,Eclipse 便會請你重新啟動或是套用變更將 plugin 完成整合到 Eclipse 中。



安裝完 PyDev 之後,別忘了先設定 PyDev,讓它瞭解 Python 被安裝在哪裡:



建立 Google App Engine 專案


設定完 Python 之後,建立新專案時,就有 PyDev Google App Engine Project 可以選擇了:



輸入專案名稱,以及別忘了選擇正確的 Python 版本:



接著選擇 Google App Engine 的安裝位置:



最後就是填入你的 application ID 及專案的範本:



如此一來專案就建立完成了。

執行及部署


當你的程式寫完,想要啟動開發用伺服器來作測試時,在專案視窗中的 src 目錄上按下右鍵,選擇 Run as... 就有 Run: Google App 可以選擇了:



如果要將應用程式部署至 Google App Engine 上,則一樣在 src 目錄上按下右鍵,選擇 PyDev: Google App Engine 就有 UploadManage 可以使用。



這樣是不是簡單多了呢?祝各位開發愉快 :-)