GAE 的很多件事筆記…

轉載跟紀錄一些蒐集到的 GAE 資料。

Gtug Taipei Gae 介紹

講者: Ikai Lan (藍奕凱), Google App Engine Developer Relations Team
講題: Quick program update and ‘GO’ language on Google App Engine

http://www.youtube.com/watch?v=1KbK9GJJOvo

GAE 的十件事

* 版本號可以用字串 
儘管在多數的例子中都將 app.yaml 和 appengine-web.xml 中的 ‘version’ 用數字表示,實際上這只是一種習慣。版本可以是任何 URL 中允許的字。例如,你可以將你的版本設置成 “live” 和 “dev”,這樣你就可以通過 “live.xxx.appspot.com” 和 “dev.xxx.appspot.com” 這樣的網址來訪問了。
* 你可以在專案中同時使用多個版本
不同的版本可以使用不同的運行環境。換言之,你可以為你的應用程式開發使用 Java 語言的版本和 Python 語言的版本。
* Java 執行時支援任何編譯成Java bytecode的語言
這就是為什麼人們需要 Jvm 的原因,一旦虛擬機器被支援了就等於你可以在 GAE 上使用JRuby, Groovy, Scala, Rhino(JavaScript 直譯器), Quercus(PHP 直譯器), 甚至 Jython(= = 某某人表示已經能跑 python 了)!

* 使用’IN’和’!=’運算符可以生成多重數據查詢
例如,查詢


SELECT * FROM People WHERE name IN ('Bob', 'Jane')

將會被編譯成兩個查詢等價於使用

SELECT * FROM People WHERE name = 'Bob'"
"SELECT * FROM People WHERE name = 'Jane'

並且合併查詢的結果。查詢

SELECT * FROM People WHERE
  name IN ('Bob', 'Jane') AND age != 25

將會為每種可能產生查詢,(age 小於或者等於25, 和 name 是否為 ‘Bob’ 或者 ‘Jane’ ),然後將每種可能合併成結果。
* 你可以使用批次處理執行 put,get 和 delete 操作來提高效率。
每當你做出一個數據請求,比如一個查詢或者 get(),你的程式將會對資料庫發出請求,而資料庫將會執行這些操作並返還一個 response。請求到回應的過程將會花費一定時間,所以如果你執行的請求過多的話將會導致用戶等待結果的時間過長(萬惡的datastore timeout: operation took too long 異常)。

很幸運的是,GAE 提供一個簡單的方法來減少資料查詢中的這種循環:批次處理操作。db.put() , db.get(), 和db.delete() 函數都可以接受 option 的 list 參數來執行操作。當一個傳遞一個 list 以後這些操作將會並行的迭代 list 的每一個元素,這樣就大大節省了操作的時間。例如:

for entity in MyModel.all().filter("color =", old_favorite).fetch(100):
   entity.color = new_favorite entity.put()

更新需要一個資料庫回應的查詢,還需要加上一次操作來更新資料庫中實體的屬性,也就是說一共需要101次週期!再看下面的例子:

updated = []
for entity in MyModel.all().filter("color =", old_favorite).fetch(100):
   entity.color = new_favorite
   updated.append(entity) db.put(updated)

這個例子中只需要2次資料庫查詢,也就是說我們將101次減少到了2次。

* 資料庫的效能不因資料數量而有影響

* 資料數量的多寡對建立索引的速度影響不大(?)

* Stored Data 的值是每天更新的

* app.yaml,web.xml 和 appengine-web.xml 中 handler 的順序即為讀取的順序

大家經常犯的錯誤是忘記配置處理設定的順序是自上而下的。比如,當使用 remote_api 時候很多人這樣做:


handlers:
 - url: /.*
   script: request.py
 - url: /remote_api
   script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
   login: admin

上面的例子看起來沒有什麼問題,但是由於 handler 是按照順序處理的,request.py 是首先出現的,而所有請求包括對 remote_api 的請求都是使用 request.py 處理的。由於 request.py 加載後並沒有出現remote_api,所以就會造成 404 Not Found error 的錯誤。解決的方法是將 request.py 的 handler 放置到remote_api 的 handler 下面。在Java環境的配置文件中也是一樣。
<strong>* 你不需要手動串接 GQL 字串(有類似 printf 的塞變數語法可以用)</strong>
下面是一個錯誤的例子:

q = db.GqlQuery("SELECT * FROM People " "WHERE first_name = '" + first_name + "' AND last_name = '" + last_name + "'")

幸運地 GAE 支持在 GqlQuery 語句中使用參數替換,上面例子可以改寫成:

q = db.GqlQuery("SELECT * FROM People " "WHERE first_name = :1 " "AND last_name = :2", first_name, last_name)

GqlQuery 還支援使用 args name 來取代數字參數:

q = db.GqlQuery("SELECT * FROM People " "WHERE first_name = :first_name " "AND last_name = :last_name", first_name=first_name, last_name=last_name)

這樣做出了能使程式看起來更加簡潔以外,還可以進行一些優化。如果你需要使用不同的值來進行多次同樣的查詢,你可以使用 bind() 函數來為每個查詢重新綁定參數。這比起每次都要構造新的查詢更加快捷,因為查詢只需要分析一次:

q = db.GqlQuery("SELECT * FROM People " "WHERE first_name = :first_name " "AND last_name = :last_name")
for first, last in people:
   q.bind(first, last)
   person = q.get()
   print person

作者Nick Johnson, App Engine Team

資料來源:

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *