使用mongo与FLASK和python [英] Using mongo with FLASK and python

查看:183
本文介绍了使用mongo与FLASK和python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图学习python,mongodb和flask,并使用来自Miguel Grinberg的VERY EXCELLENT博客,他在blog.miguelgrinberg.com上提供了一系列教程。

我有一个小的RESTful服务器工作正常,但现在想要从Mongo拉东西,而不是MySQL

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

我在下面的代码中使用了箭头来显示我在挣扎的地方,我觉得缺乏经验。任何想法,将不胜感激。

 #!flask / bin / python 
从瓶子导入烧瓶,jsonify,中止, make_response,url_for
from pymongo import MongoClient

#连接到AWS上的mongo数据库
#脚本需要主机名在/ etc / hosts文件中

'''
在这里设置全局变量
'''
mongo_server =mongo_api
mongo_port =27017
mongo_user =admin
mongo_passwd = :mysecretpassword @
CONNECT_STRING = mongodb的:// + mongo_user
+ mongo_passwd
+ mongo_server
+ :
+ mongo_port

应用程式=烧瓶(__ name__)

@ app.errorhandler(404)
DEF NOT_FOUND(误差):
返回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


$ b @ app.route('/ api / v1.0 / pages / < int:page_id>'方法= ['GET'])
def get_page(page_id):
'''
可以连接,否则退出消息
'''
尝试:
连接= MongoClient(connect_string)#等于>显示数据库
,除了:
exit(错误:无法连接到数据库)#退出时出现错误
'''
连接数据库并拉回集合
'''
db = connection.test_database#等于>使用test_database
pages = db.pages
page = pages.find_one({id:int(page_id)})< ------这将文件拉回
if页面==无:< ----如果空集合回来,那么这个工程很好
abort(404)
return jsonify({'page':make_public_page(page [0])}) < - 错误说不是json

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

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



在此先感谢



BTW不能推荐米格尔的大型教程足以作为开始构建的地方

如果集合中没有匹配的元素,c>将返回单个字典或None。所以我认为 page [0] 相当于获取关键字 0

$的页面字典值b
$ b

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

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

只需通过调用 page.pop('_ id') $ b $来删除 _id b

您也可以使用 bson.json_util 。它包含BSON和JSON之间转换的工具。

  from flask import响应
from bson import json_util

然后用类似下面的内容替换 jsonify

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

编辑

  from bson import json_util 

如果你想处理这个问题的方法很简单,你可以这样做: ,ObjectId
导入json

#让我们创建一个伪文档来证明它会起作用
page = {'foo':ObjectId(),'bar':[ObjectId() ,ObjectId()]}

#Dump加载BSON为有效的JSON字符串并重新加载为字典
page_sanitized = json.loads(json_util.dumps(page))


I am trying to learn python, mongodb and flask and am using the VERY EXCELLENT blog from Miguel Grinberg who provides a great set of tutorials at blog.miguelgrinberg.com

I got a small RESTful server working fine but now want to pull stuff from mongo not mysql

I can pull a mongo record out using the code below but am struggling to get it to render.

I have used arrows in the code below to show where I am struggling, lack of experience I think. Any thoughts would be appreciated.

#!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)

Any help appreciated, page[0] is the code that's just not working I get a

TypeError: ObjectId('527e17c538320915e9893f17') is not JSON serializable

Thanks in advance

BTW Can't recommend Miguel's mega tutorial enough as a place to start to build stuff

解决方案

First of all find_one will return single dictionary or None if there is no matching element in collection. So I think that page[0] is equivalent to getting value of page dictionary for key 0

If returned documents contains ObjectId as _id you cannot simply use jsonify because, like ObjectId is not JSON serializable. You can use something like this:

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

or you can simply remove _id by calling page.pop('_id')

You can also use bson.json_util. It contains tools for conversion between BSON and JSON.

from flask import Response 
from bson import json_util

And then replace jsonify with something similar to this:

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

Edit

If you want short and dirty way of dealing with the problem you can do it like this:

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))

这篇关于使用mongo与FLASK和python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆