作者:
K_Reverter 來源:
博客園 發(fā)布時間:2009-04-07 19:47 閱讀:1342 次
原文鏈接
[收藏]
GAE的數(shù)據(jù)庫是支持向里面保存文件的(說老實話,就算不支持,通過對二進(jìn)制轉(zhuǎn)化為文本肯定也是可以保存的),這個功能我知道,不過我的用不著,因為我的網(wǎng)站文件并不多,數(shù)據(jù)庫卻大的不行,我一直在苦惱如何去節(jié)省數(shù)據(jù)庫空間,而從來不去想如何節(jié)省文件空間,可是有一個網(wǎng)友一定要我研究一下(主要是有些人比較懶,不想研究,唉?。?,我只好簡單的進(jìn)行了一下研究,還好,還是比較容易的,現(xiàn)在將主要的流程講一下。
首先當(dāng)然是怎么向數(shù)據(jù)庫之中存文件,我僅僅研究了通過本地向遠(yuǎn)程數(shù)據(jù)庫上傳靜態(tài)文件的模式,想來,通過服務(wù)器創(chuàng)建二進(jìn)制文件并保存也沒有什么不同。我使用python腳本實現(xiàn)了一個方便的工具,一旦運(yùn)行這個腳本,就會將該腳本所在位置uploadFiles文件夾下面的內(nèi)容上傳到GAE的數(shù)據(jù)庫之中,下面是該腳本的源碼,那是相當(dāng)?shù)暮唵伟。?/p>

# -*- coding: utf-8 -*- #
import code
import getpass
import sys
import os

sys.path.append("D:\Program Files\Google\google_appengine\lib\yaml\lib")
sys.path.append("D:\Program Files\Google\google_appengine")

from google.appengine.ext.remote_api import remote_api_stub
from google.appengine.ext import db
#數(shù)據(jù)格式定義
class FileData(db.Model):
category = db.CategoryProperty(required=True)
uploadTime = db.DateTimeProperty(auto_now= True )
path = db.StringProperty(required=True)
content = db.BlobProperty(required=True)
#如果你將你的用戶名和密碼寫在這個函數(shù)里面,就不用每次輸入用戶名和密碼了
def auth_func():
return raw_input('Username:'), getpass.getpass('Password:')

def walkdir(dirname):
ls=os.listdir(dirname)
for l in ls:
path=os.path.join(dirname,l)
if(os.path.isdir(path)):
walkdir(path)
else:
f=open(path,"rb")
content=f.read()
f.close()
item=FileData(category='Test',path=path.replace("\\","/").replace(rootPath,""),content=content)
db.put(item)
#配置要上傳的文件夾路徑
rootPath="./uploadFiles"
#下面一句配置連接remote_api的路徑,至于怎么部署remote_api,看GAE文檔和我以前的文章
remote_api_stub.ConfigureRemoteDatastore("yourappid", '/remote_api',auth_func)
#遍歷文件夾
walkdir(rootPath)
print "OK"
因為我無意于使用該功能,所以上面的腳本做的很簡單,具體的使用可以自己擴(kuò)充更改,腳本只需要配置上傳文件夾路徑、appid、remote_api路徑三項就應(yīng)該可以運(yùn)行了。
上傳成功之后,可以在GAE后臺看到數(shù)據(jù),對于content字段,在GAE后臺顯示為類似"156240 bytes, SHA-1 = 1d616cd4cd0de8e26f350143e29b3cc63e156825"的描述文本。
下面的問題是如何調(diào)用和返回這個內(nèi)容,這更加容易了,我是采用以下方式來返回此文件的:
result=FileData.all().filter("path = ",path).fetch(1)
if len(result)>0:
self.response.out.write(result[0].content)
else:
self.response.set_status(404)
很輕松容易吧,事實上就是這么簡單的,有些網(wǎng)友不怎么喜歡研究,這一點要好好批評一下!