YORKXIN×YORKXIN

鴨七的人生,不是夜市人生

Google App Engine Oil 與 Bulkloader 大量上傳資料庫內容

leave a comment »

剛剛試出來的,我原本還不相信我試得出來。

總之現在的作業是:

Google App Engine Oil 開發 Google App Engine 的網頁應用程式。請透過 bulkloader 把某個 Kind 的 Entities 匯入到 Datastore 裏面。

這個時候當然是先看官方的說明了, Uploading Data – Google App Engine

首先第一步當然是設定環境:

app.yamlheader: 底下加入這幾行:

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

接著你手邊應該要準備你要匯入的資料,它是 CSV 格式,以半形逗號 `,‘ 分隔欄位,並以換行分隔每一筆 record (row, datum etc.),編碼是 UTF-8。例如這樣:

Google App Engine Bulkloader CSV Sample

接下來要寫一個 BulkLoader 的程式。

這裡注意一下,因為我是用 Google App Engine Oil 寫的程式,所以跟官方的範例有點出入 (官方的範例是假設你的 AlbumModel 放在 根目錄/models.py 裏面),但很顯然我試不出來 GAEO 要怎麼搞,所以我的做法是,把 model 的定義 (一個 class) 直接複製到現在要寫的 bulkloader 程式裏面,然後把 BaseModel 改成 db.Model,也就是去繼承 db.Model 這個 class 。

下面這支程式我把檔案名稱設成 college_loader.py 。

from google.appengine.ext import db
from google.appengine.tools import bulkloader
# 以下是 Model 的 Definition
class College(db.Model):
    cid = db.StringProperty(required=True)
    name = db.StringProperty(required=True)

# 以下是匯入資料的 class
class CollegeLoader(bulkloader.Loader):
    def __init__(self):
        bulkloader.Loader.__init__(self, 'College',
                                   [('cid', str),
                                   ('name', str)
                                   ])

loaders = [CollegeLoader]

寫完之後,基本上就可以 run 了。

我的程式是這樣放的:

  • /
    • bulkloader/
      • college_loader.py
      • data/
        • colleges.csv

可以看得出來,我把 bulkloader 和相關的東西放在另一個資料夾裏面方便管理。

接著就可以測試匯入了。先在本機的 development 測試。所以這裡的 url 是 localhost 的。

依照官方的文件教學,我應該要在程式的根目錄執行:

appcfg.py upload_data \
--config_file=bulkloader/college_loader.py \
--filename=bulkloader/data/colleges.csv \
--kind=College \
--url=http://localhost:8080/remote_api \
.

最後面那個 . 表示「目前路徑」,是給 appcfg.py 吃  <application_path> 的參數。

接著它會出現兩個提示。由於我們是在測試環境,所以 Email 和 Password 隨便打就行了,會自動登入成 administrator:

Please enter login credentials for localhost
Email: test@example.com
Password for test@example.com:

但就在這個時候慘絕人寰的事又發生了

它噴 Error !

它噴 Error !

它噴一大堆 Error !

開頭大概是長這樣:

[INFO    ] [Thread-10] BulkLoaderThread: started
[ERROR   ] [Thread-1] BulkLoaderThread: caught exception (<type 'exceptions.UnicodeDecodeError'>, UnicodeDecodeError('ascii', '\xe5\x9c\x8b\xe7\xab\x8b\xe8\x87\xba\xe7\x81\xa3\xe5\xa4\xa7\xe5\xad\xb8', 0, 1, 'ordinal not in range(128)'), <traceback object at 0x123e148>)

俗話說得好(?),Error Message 丟到 Google 就有答案,是的,把上面紅色的部份 (是我自己上的色) 丟到 Google ,就有答案↓

http://code.google.com/p/googleappengine/issues/detail?id=157#c18

簡單來說,就是把那個 Bulkloader 的 Column Type 改一下


class CollegeLoader(bulkloader.Loader):
    def __init__(self):
        bulkloader.Loader.__init__(self, 'College',
                                   [('cid', str),
                                   """ 改下面這一行 """
                                   ('name', lambda x: unicode(x, 'utf-8'))
                                   ])

醬子就可以了,再跑一次工序指令:

Google App Engine Bulkloader

是的,到 localhost:8080/_ah/admin 裏面看就有了!

Google App Engine Bulkloaded Datastore

至於 GAEO 能不能吃呢?當然可以啊!

application/controller/college.py

from google.appengine.ext import db

from gaeo.controller import BaseController
from model.college import College

class CollegeController(BaseController):
    def index(self):
        self.colleges = College.all()
        pass

application/model/college.py

from google.appengine.ext import db
from gaeo.model import BaseModel, SearchableBaseModel

class College(BaseModel):
    cid = db.StringProperty(required=True)
    name = db.StringProperty(required=True)

application/model/college.py

{% if colleges %}
<ul>
        {% for college in colleges %}
	<li>{{ college.cid }} {{ college.name }}</li>
{% endfor %}</ul>
{% else %}
    <strong>There's no colleges</strong>
{% endif %}

然後用瀏覽器開 /college 這個 path。

那要怎麼把資料丟到 Google App Engine 的 Server 呢?

首先先把程式碼 Update 上去:

appcfg.py update .

然後一樣執行 upload_data 的工序指令,只是因為這個工序指令預設就是丟到遠端 server ,所以參數相對少了許多,都給他預設值了:

appcfg.py upload_data \
--config_file=bulkloader/college_loader.py \
--filename=bulkloader/data/colleges.csv \
--kind=College \
.

會要求輸入你的 Google 帳號及密碼。

沒有 Error 的話,就完成了。

Google App Engine Bulkloaded Remote Datastore

作者為Chitsaou Yorkxin

2009 年 五月 5 日 星期二 於 22:09:01

發表迴響