将mongo与FLASK和python一起使用
我正在努力学习python、mongodb和flask,我正在使用Miguel Grinberg的非常优秀的博客,他在blog.miguelgrinberg.com上提供了一套非常好的教程 我有一个小的RESTful服务器工作正常,但现在想从mongo而不是mysql中提取东西 我可以使用下面的代码拉出mongo记录,但我很难让它呈现出来 我在下面的代码中使用了箭头来显示我在哪里挣扎,我认为缺乏经验。如有任何想法,将不胜感激将mongo与FLASK和python一起使用,python,mongodb,flask,Python,Mongodb,Flask,我正在努力学习python、mongodb和flask,我正在使用Miguel Grinberg的非常优秀的博客,他在blog.miguelgrinberg.com上提供了一套非常好的教程 我有一个小的RESTful服务器工作正常,但现在想从mongo而不是mysql中提取东西 我可以使用下面的代码拉出mongo记录,但我很难让它呈现出来 我在下面的代码中使用了箭头来显示我在哪里挣扎,我认为缺乏经验。如有任何想法,将不胜感激 #!flask/bin/python from flask impor
#!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)
#!烧瓶/箱/蟒蛇
从烧瓶导入烧瓶,jsonify,abort,make_响应,url_
从pymongo导入MongoClient
#连接到AWS上托管的mongo数据库
#脚本希望主机名位于/etc/hosts文件中
'''
在这里设置全局变量
'''
mongo_服务器=“mongo_api”
mongo_port=“27017”
mongo_user=“admin”
mongo_passwd=“:mysecretpassword@”
connect_string=“mongodb://”+mongo\u用户
+蒙哥路
+mongo_服务器
+ ":"
+蒙哥乌港
app=烧瓶(名称)
@app.errorhandler(404)
未找到def_(错误):
返回make_响应(jsonify({'error':'Notfound}),404)
def公开页面(第页):
新页面={}
对于第页中的字段:
如果字段=='id':
新建页面['uri']=url\for('get\u page',page\u id=page['id'],\u external=True)
其他:
新建页面[字段]=页面[字段]
返回新页面
@app.route('/api/v1.0/pages/',方法=['GET'])
def get_页面(页面id):
'''
可以连接,否则退出消息
'''
尝试:
连接=MongoClient(连接字符串)#等于>显示数据库
除:
退出(“错误:无法连接到数据库”)#退出时出错
'''
连接到数据库并拉回集合
'''
db=connection.test#u数据库#等于>使用test#u数据库
pages=db.pages
page=pages.find_one({“id”:int(page_id)})首先find_one
将返回单个字典,如果集合中没有匹配的元素,则返回None。所以我认为page[0]
相当于获取键0
page字典的值
如果返回的文档包含ObjectId
作为\u id
,则不能简单地使用jsonify
,因为,likeObjectId
是不可JSON序列化的。
您可以使用以下内容:
jsonify({ 'page': make_public_page({k:v for k, v in page.items() if k != '_id'}))
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))
或者您可以通过调用page.pop(“u id”)
您也可以使用。它包含用于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'
)
编辑
如果你想用简短而肮脏的方式处理问题,你可以这样做:
jsonify({ 'page': make_public_page({k:v for k, v in page.items() if k != '_id'}))
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自己的id(存储在key\u id
中),而是生成自己的整数id,存储在keyid
中。这是正确的吗
代码的问题是Mongo\u id
键位于发送到公开页面()
的dict
对象中,这些对象无法序列化为JSON
您可以通过跳过键\u 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。您可以设置默认编码器:
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.jsonecoder子类化是的,您是对的,我带着自己的ID,对mongo和nosql来说非常陌生,因此仍然处于学习曲线的陡峭部分。关于使用本机_id的好建议,它永远不会知道它无法转换mongo值。非常感谢我明天继续。谢谢你使用你的页面。pop(“u id”)看起来和Miguels解释结合起来会有帮助。感谢您抽出时间回复,非常感谢。我没有足够的代表来推广这个答案,但是当我发布了一个关于处理这个问题的替代方法的编辑后,我会的。这不是很优雅,但很有效。虽然已经晚了,但你可以看看,这是一个mongodb/Flask网站框架,有一些使用示例(用户登录等)