首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将mongo与FLASK和python结合使用

将mongo与FLASK和python结合使用
EN

Stack Overflow用户
提问于 2013-11-09 23:54:32
回答 3查看 23K关注 0票数 9

我正在尝试学习python、mongodb和flask,并且正在使用Miguel Grinberg的非常优秀的博客,他在blog.miguelgrinberg.com上提供了一组很好的教程。

我有一个运行良好的小型RESTful服务器,但现在我想从mongo而不是mysql中拉出一些东西。

我可以使用下面的代码拉出一个mongo记录,但我正在努力让它呈现出来。

我在下面的代码中使用了箭头来显示我在哪里挣扎,我认为缺乏经验。任何想法都将不胜感激。

代码语言:javascript
复制
#!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)

感谢任何帮助,页面是不工作的代码,我得到了一个

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

提前感谢

顺便说一句,不能推荐Miguel的巨型教程作为开始构建东西的起点

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-10 00:09:29

首先,find_one将返回单个字典,如果集合中没有匹配的元素,则返回None。所以我认为page[0]等同于获取关键0页面字典的值

如果返回的文档包含ObjectId作为_id,则不能简单地使用jsonify,因为像ObjectId一样,JSON是不可序列化的。您可以使用类似以下内容:

代码语言:javascript
复制
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之间进行转换的工具。

代码语言:javascript
复制
from flask import Response 
from bson import json_util

然后将jsonify替换为类似如下的内容:

代码语言:javascript
复制
return Response(
    json_util.dumps({'page' : make_public_page(page)}),
    mimetype='application/json'
)

编辑

如果你想用短而脏的方法来处理这个问题,你可以这样做:

代码语言:javascript
复制
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))
票数 12
EN

Stack Overflow用户

发布于 2014-07-06 23:20:29

您可以设置默认编码器:

代码语言:javascript
复制
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的子类

票数 2
EN

Stack Overflow用户

发布于 2013-11-10 03:03:01

从我在您的代码中看到的,您似乎没有使用Mongo自己的it (存储在key _id中),而是生成您自己的整数it,并将其存储在key id中。这是正确的吗?

您的代码的问题是MongoJSON键在您发送到make_public_page()dict对象中,而这些对象不能序列化为_id

您可以通过跳过key _id来解决此问题

代码语言:javascript
复制
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。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19877903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档