Google App Engine Oil 與 Bulkloader 大量上傳資料庫內容
剛剛試出來的,我原本還不相信我試得出來。
總之現在的作業是:
以 Google App Engine Oil 開發 Google App Engine 的網頁應用程式。請透過
bulkloader把某個 Kind 的 Entities 匯入到 Datastore 裏面。
這個時候當然是先看官方的說明了, Uploading Data – Google App Engine。
首先第一步當然是設定環境:
在 app.yaml 的 header: 底下加入這幾行:
- url: /remote_api script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py login: admin
接著你手邊應該要準備你要匯入的資料,它是 CSV 格式,以半形逗號 `,‘ 分隔欄位,並以換行分隔每一筆 record (row, datum etc.),編碼是 UTF-8。例如這樣:
接下來要寫一個 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'))
])
醬子就可以了,再跑一次工序指令:
是的,到 localhost:8080/_ah/admin 裏面看就有了!
至於 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 的話,就完成了。




