簡體   English   中英

在 FLASK 和 python 中使用 mongo

[英]Using mongo with FLASK and python

我正在嘗試學習 python、mongodb 和flask,並且正在使用 Miguel Grinberg 的非常優秀的博客,他在 blog.miguelgrinberg.com 上提供了一套很棒的教程

我有一個小型 RESTful 服務器工作正常,但現在想從 mongo 而不是 mysql 中提取東西

我可以使用下面的代碼提取 mongo 記錄,但正在努力讓它呈現。

我在下面的代碼中使用了箭頭來顯示我在哪里掙扎,我認為缺乏經驗。 任何想法將不勝感激。

#!flask/bin/python
from flask import Flask, jsonify, abort, make_response, url_for
from pymongo import MongoClient

# connect to mongo database hosted on AWS
# the script expects the host name to be in  /etc/hosts file

'''
Set up global variables here
'''
mongo_server = "mongo_api"
mongo_port = "27017"
mongo_user = "admin"
mongo_passwd = ":mysecretpassword@"
connect_string = "mongodb://"+ mongo_user 
                             + mongo_passwd 
                             + mongo_server 
                             + ":" 
                             + mongo_port

app = Flask(__name__)

@app.errorhandler(404)
def not_found(error):
    return make_response(jsonify( { 'error': 'Notfound' } ), 404)


def make_public_page(page):
    new_page = {}
    for field in page:
        if field == 'id':
            new_page['uri'] = url_for('get_page', page_id = page['id'], _external = True)
        else:
            new_page[field] = page[field]
    return new_page



@app.route('/api/v1.0/pages/<int:page_id>',methods = ['GET'])
def get_page(page_id):
    '''
    Can connect otherwise exit with message
    '''
    try:
        connection = MongoClient(connect_string)    # equal to > show dbs
    except:
        exit("Error: Unable to connect to the database") # exit with an error
    '''
    connect to database and pull back collections
    '''
    db = connection.test_database # equal to > use test_database                
    pages = db.pages
    page = pages.find_one({"id": int(page_id)})   <------ this pulls back a document
    if page == None:  <---- if a null set comes back then this works great
        abort(404)
    return jsonify( { 'page' : make_public_page(page[0])} ) <- error says its not json

if __name__ == '__main__':
    app.run(debug = True)

感謝任何幫助,頁面 [0] 是無法正常工作的代碼,我得到了

TypeError: ObjectId('527e17c538320915e9893f17') 不是 JSON 可序列化的

提前致謝

順便說一句,不能推薦 Miguel 的大型教程足以作為開始構建東西的地方

首先find_one將返回單個字典或 None 如果集合中沒有匹配的元素。 所以我認為page[0]相當於獲取 key 0的 page 字典的0

如果返回的文檔包含ObjectId作為_id ,則不能簡單地使用jsonify因為ObjectId不是 JSON 可序列化的。 你可以使用這樣的東西:

jsonify({ 'page': make_public_page({k:v for k, v in page.items() if k != '_id'}))

或者您可以通過調用page.pop('_id')簡單地刪除_id

您也可以使用bson.json_util 它包含用於在 BSON 和 JSON 之間轉換的工具。

from flask import Response 
from bson import json_util

然后用類似的東西替換jsonify

return Response(
    json_util.dumps({'page' : make_public_page(page)}),
    mimetype='application/json'
)

編輯

如果您想要處理問題的簡短而骯臟的方式,您可以這樣做:

from bson import json_util, ObjectId
import json

#Lets create some dummy document to prove it will work
page = {'foo': ObjectId(), 'bar': [ObjectId(), ObjectId()]}

#Dump loaded BSON to valid JSON string and reload it as dict
page_sanitized = json.loads(json_util.dumps(page))

您可以設置默認編碼器:

import json
from bson.objectid import ObjectId

def newEncoder(o):
    if type(o) == ObjectId:
        return str(o)
    return o.__str__

....

return json.dumps(list(somecollection.find(expr)) ,  default=newEncoder )

或者你可以繼承 json.encoder.JSONEncoder

從我在您的代碼中看到的內容來看,您似乎沒有使用 Mongo 自己的 ID(存儲在鍵_id ),而是生成自己的整數 ID,並將其存儲在鍵id 這樣對嗎?

您的代碼的問題在於 Mongo _id鍵位於您發送到make_public_page()dict對象中,而這些對象無法序列化為 JSON。

您可以通過跳過鍵_id來解決此問題:

def make_public_page(page):
    new_page = {}
    for field in page:
        if field == 'id':
            new_page['uri'] = url_for('get_page', page_id = page['id'], _external = True)
        elif field != '_id':
            new_page[field] = page[field]
    return new_page

作為旁注,我認為最好不要發明自己的 ID,而只使用 Mongo 的 ID。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM