1、前期準備
通過 pip 或 easy_install 安裝了 pymongo 之后, 就能通過 Python 調教 mongodb 了.
接著安裝個 flask 用來當 web 服務器.
當然 mongo 也是得安裝的. 對于 Ubuntu 用戶, 特別是使用 Server 12.04 的同學, 安裝最新版要略費些周折, 具體說是
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.listsudo apt-get updatesudo apt-get install mongodb-10gen
如果你跟我一樣覺得讓通過上傳文件名的后綴判別用戶上傳的什么文件完全是捏著山藥當小黃瓜一樣欺騙自己, 那么最好還準備個 Pillow 庫
代碼如下:
pip install Pillow
或 (更適合 Windows 用戶)
代碼如下:
easy_install Pillow
2、正片
2.1 Flask 文件上傳
Flask 官網上那個例子居然分了兩截讓人無從吐槽. 這里先弄個最簡單的, 無論什么文件都先弄上來
import flaskapp = flask.Flask(__name__)app.debug = [email protected]('/upload', methods=['POST'])def upload(): f = flask.request.files['uploaded_file'] print f.read() return flask.redirect('/')@app.route('/')def index(): return ''' <!doctype html> <html> <body> <form action='/upload' method='post' enctype='multipart/form-data'> <input type='file' name='uploaded_file'> <input type='submit' value='Upload'> </form> '''if __name__ == '__main__': app.run(port=7777)
注: 在 upload 函數中, 使用 flask.request.files[KEY] 獲取上傳文件對象, KEY 為頁面 form 中 input 的 name 值
因為是在后臺輸出內容, 所以測試最好拿純文本文件來測.
2.2 保存到 mongodb
如果不那么講究的話, 最快速基本的存儲方案里只需要
import pymongoimport bson.binaryfrom cStringIO import StringIOapp = flask.Flask(__name__)app.debug = Truedb = pymongo.MongoClient('localhost', 27017).testdef save_file(f): content = StringIO(f.read()) db.files.save(dict( content= bson.binary.Binary(content.getvalue()), ))@app.route('/upload', methods=['POST'])def upload(): f = flask.request.files['uploaded_file'] save_file(f) return flask.redirect('/')
把內容塞進一個 bson.binary.Binary 對象, 再把它扔進 mongodb 就可以了.
現在試試再上傳個什么文件, 在 mongo shell 中通過 db.files.find() 就能看到了.
不過 content 這個域幾乎肉眼無法分辨出什么東西, 即使是純文本文件, mongo 也會顯示為 Base64 編碼.
2.3 提供文件訪問
給定存進數據庫的文件的 ID (作為 URI 的一部分), 返回給瀏覽器其文件內容, 如下
def save_file(f): content = StringIO(f.read()) c = dict(content=bson.binary.Binary(content.getvalue())) db.files.save(c) return c['_id']@app.route('/f/<fid>')def serve_file(fid): f = db.files.find_one(bson.objectid.ObjectId(fid)) return f['content']@app.route('/upload', methods=['POST'])def upload(): f = flask.request.files['uploaded_file'] fid = save_file(f) return flask.redirect( '/f/' + str(fid))
新聞熱點
疑難解答