最新消息:VPS服务器又从fzhost.net换回Linode了,主题仍用朋友推荐的大前端D8

【已解决】Flask中连接远程MongoDB数据库的gridfs并返回查询到的文件数据

Flask crifan 16浏览 0评论

折腾:

【已解决】CentOS服务器中搭建Python的Flask的REST API

期间,接着折腾。

去尝试连接远程的MongoDB,并且连接后,去查询gridfs中是否有想要的文件名的数据并返回

flask mongodb

Flask-PyMongo — Flask-PyMongo 0.5.1 documentation

Flask扩展系列(五)–MongoDB – 思诚之道

  • Flask-MongoAlchemy

    • 类似于SQLAlchemy

  • Flask-MongoKit

  • PyMongo

Flask PyMongo 中文文档 | Flask 扩展文档汇总

Flask 中 MongoDB 的使用 – 简书

MongoKit in Flask — Flask Documentation (0.12)

PyMongo 3.6.1 Documentation — PyMongo 3.6.1 documentation

dcrosta/flask-pymongo: PyMongo support for Flask applications

决定用:flask-pymongo

先去安装:

<code>➜  robotDemo pipenv install flask-pymongo
Installing flask-pymongo…
Collecting flask-pymongo
  Downloading https://files.pythonhosted.org/packages/fa/71/ab920741dedd605ef4adbd57d0c7d9f43a6b6fe4068604fffbc6f64b2c9c/Flask_PyMongo-0.5.1-py3-none-any.whl
Requirement already satisfied: Flask&gt;=0.8 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from flask-pymongo) (0.12.2)
Collecting PyMongo&gt;=2.5 (from flask-pymongo)
  Downloading https://files.pythonhosted.org/packages/5c/7f/1f7240883ec3fa768d7e066c9cbd42ceb42d699ba1a0fb9d231c098a542d/pymongo-3.6.1-cp36-cp36m-macosx_10_6_intel.whl (316kB)
Requirement already satisfied: click&gt;=2.0 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask&gt;=0.8-&gt;flask-pymongo) (6.7)
Requirement already satisfied: itsdangerous&gt;=0.21 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask&gt;=0.8-&gt;flask-pymongo) (0.24)
Requirement already satisfied: Jinja2&gt;=2.4 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask&gt;=0.8-&gt;flask-pymongo) (2.10)
Requirement already satisfied: Werkzeug&gt;=0.7 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Flask&gt;=0.8-&gt;flask-pymongo) (0.14.1)
Requirement already satisfied: MarkupSafe&gt;=0.23 in /Users/crifan/.local/share/virtualenvs/robotDemo-HXjMJQEQ/lib/python3.6/site-packages (from Jinja2&gt;=2.4-&gt;Flask&gt;=0.8-&gt;flask-pymongo) (1.0)
Installing collected packages: PyMongo, flask-pymongo
Successfully installed PyMongo-3.6.1 flask-pymongo-0.5.1

Adding flask-pymongo to Pipfile's [packages]…
Pipfile.lock (09e966) out of date, updating to (36c54e)…
Locking [dev-packages] dependencies…
Locking [packages] dependencies…
Updated Pipfile.lock (36c54e)!
Installing dependencies from Pipfile.lock (36c54e)…
  🐍   ▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉ 12/12 — 00:00:03
To activate this project's virtualenv, run the following:
 $ pipenv shell
➜  robotDemo pipenv graph
Flask-PyMongo==0.5.1
  - Flask [required: &gt;=0.8, installed: 0.12.2]
    - click [required: &gt;=2.0, installed: 6.7]
    - itsdangerous [required: &gt;=0.21, installed: 0.24]
    - Jinja2 [required: &gt;=2.4, installed: 2.10]
      - MarkupSafe [required: &gt;=0.23, installed: 1.0]
    - Werkzeug [required: &gt;=0.7, installed: 0.14.1]
  - PyMongo [required: &gt;=2.5, installed: 3.6.1]
Flask-RESTful==0.3.6
  - aniso8601 [required: &gt;=0.82, installed: 3.0.0]
  - Flask [required: &gt;=0.8, installed: 0.12.2]
    - click [required: &gt;=2.0, installed: 6.7]
    - itsdangerous [required: &gt;=0.21, installed: 0.24]
    - Jinja2 [required: &gt;=2.4, installed: 2.10]
      - MarkupSafe [required: &gt;=0.23, installed: 1.0]
    - Werkzeug [required: &gt;=0.7, installed: 0.14.1]
  - pytz [required: Any, installed: 2018.4]
  - six [required: &gt;=1.3.0, installed: 1.11.0]

</code>

然后去写代码

结果出错:

【已解决】Flask-PyMongo出错:RuntimeError Working outside of application context

然后继续去find对应的gridfs中的文件:

【规避解决】Flask-PyMongo中如何查询gridfs中的文件

最后是去用代码:

<code>from flask import Flask
from flask import jsonify
from flask_restful import Resource, Api, reqparse
import logging
from logging.handlers import RotatingFileHandler
# from flask_pymongo import PyMongo
from gridfs import GridFS
from pymongo import MongoClient

import re


app = Flask(__name__)

FLASK_APP = "RobotQA"

LOG_FILE_FILENAME = "logs/" + FLASK_APP + ".log"
LOG_FORMAT = "[%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s] %(message)s"

app.config['LOG_FILE_FILENAME'] = LOG_FILE_FILENAME
app.config["LOG_FORMAT"] = LOG_FORMAT

logFormatterStr = app.config["LOG_FORMAT"]
logFormatter = logging.Formatter(logFormatterStr)

fileHandler = RotatingFileHandler(
    app.config['LOG_FILE_FILENAME'],
    maxBytes=2*1024*1024,
    backupCount=3,
    encoding="UTF-8")
fileHandler.setLevel(logging.DEBUG)
fileHandler.setFormatter(logFormatter)
app.logger.addHandler(fileHandler)

streamHandler = logging.StreamHandler()
streamHandler.setFormatter(logFormatter)
streamHandler.setLevel(logging.INFO)
app.logger.addHandler(streamHandler)

app.logger.setLevel(logging.DEBUG) # set root log level

log = app.logger
log.debug("debug: app=%s", app)

api = Api(app)
log.info("api=%s", api)

# Flask-PyMongo NOT work: gridfs can NOT find files
# app.config.update(
#     MONGO_HOST='x.x.x.x',
#     MONGO_PORT=12345,
#     MONGO_USERNAME='gridfs',
#     MONGO_PASSWORD=‘xxx',
#     MONGO_DBNAME='gridfs'
# )
# flaskPymongo = PyMongo(app)
# log.info("flaskPymongo=%s", flaskPymongo)

# purePymongo = MongoClient(mongodbUri)
purePymongo = MongoClient(
    host="x.x.x.x",
    port=12345,
    username="gridfs",
    password=“xxx",
    authSource="gridfs"
)
log.info("purePymongo=%s", purePymongo)

# Pure PyMongo
gridfsDb = purePymongo.gridfs  # Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=False, connect=True, authsource='gridfs'), 'gridfs')
logging.info("gridfsDb=%s", gridfsDb)
fsCollection = GridFS(gridfsDb)  # &lt;gridfs.GridFS object at 0x1107b2390&gt;
logging.info("fsCollection=%s", fsCollection)


class RobotAPI(Resource):

    def get(self):
        respDict = {
            "code": 200,
            "message": "generate answer ok",
            "data": {
                "answer": "None",
                "audio": {}
            }
        }

        parser = reqparse.RequestParser()
        parser.add_argument('q', type=str, help="input question") # play a Christmas song
        log.info("parser=%s", parser)

        parsedArgs = parser.parse_args() #{'q': 'play a sleep song'}
        log.info("parsedArgs=%s", parsedArgs)
        if not parsedArgs:
            respDict["data"]["answer"] = "Can not recognize question"
            return jsonify(respDict)

        q = parsedArgs["q"]
        log.info("q=%s", q)

        if not q:
            respDict["data"]["answer"] = "Can not recognize parameter q"
            return jsonify(respDict)

        foundSongName = re.search("play a (?P&lt;songName&gt;.+?) song", q)
        log.info("foundSongName=%s", foundSongName)
        if not foundSongName:
            respDict["data"]["answer"] = "Can not recognize song name"
            return jsonify(respDict)

        songName = foundSongName.group("songName")
        log.info("songName=%s", songName)

        # # Flask-PyMongo
        # mongoDb = flaskPymongo.db #Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs')
        # log.info("mongoDb=%s", mongoDb)
        # gridfsDb = mongoDb.gridfs #Collection(Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs'), 'gridfs')
        # log.info("gridfsDb=%s", gridfsDb)
        # fsCollection = gridfsDb.fs #Collection(Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs'), 'gridfs.fs')
        # log.info("fsCollection=%s", fsCollection)
        # filesCollection = fsCollection.files # Collection(Database(MongoClient(host=['x.x.x.x:12345'], document_class=dict, tz_aware=True, connect=True, replicaset=None), 'gridfs'), 'gridfs.fs.files')
        # log.info("filesCollection=%s", filesCollection)

        # fsFindOne = fsCollection.find_one()  # &lt;gridfs.grid_file.GridOut object at 0x110a87fd0&gt;
        # log.info("fsFindOne=%s", fsFindOne)

        # gridFineOne = gridfsDb.find_one() #
        # log.info("gridFineOne=%s", gridFineOne)
        #
        # filesFindOne = filesCollection.find_one()
        # log.info("filesFindOne=%s", filesFindOne)

        filenameRegex = re.compile(songName, re.IGNORECASE)
        log.info("filenameRegex=%s", filenameRegex)
        # findFileCursor = gridfsDb.fs.find({"filename": findRegex})
        # findFileCursor = gridfsDb.fs.find({"filename": {"$regex": findRegex, "$options": "i"}})
        # findFileCursor = fsCollection.find({"filename": {"$regex": "sleep"}})
        # findFileCursor = fsCollection.find({"filename": {"$regex": "sleep", "$options": "i"}})
        findFileCursor = fsCollection.find({"filename": {"$regex": filenameRegex, "$options": "i"}})
        log.info("findFileCursor=%s", findFileCursor)
        findFileCount = findFileCursor.count()
        log.info("findFileCount=%s", findFileCount)
        if findFileCount &lt;= 0:
            respDict["data"]["answer"] = "Can not found any file for name %s" % (songName)
            return jsonify(respDict)

        lastFoundAudio = None
        for curIdx, eachFile in enumerate(findFileCursor):
            curNum = curIdx + 1
            log.info("[%d] contentType=%s, filename=%s", curNum, eachFile.contentType, eachFile.filename)
            if re.match("audio/", eachFile.contentType):
                lastFoundAudio = eachFile

        if not lastFoundAudio:
            respDict["data"]["answer"] = "Found file but not found audio song"
            return jsonify(respDict)

        respDict["data"] = {
            "answer": "Now will play a %s song %s" % (songName, lastFoundAudio.filename),
            "audio": {
                "contentType": lastFoundAudio.contentType,
                "name": lastFoundAudio.filename,
                "url": "http://x.x.x.x/%s" % (lastFoundAudio.filename)
            }
        }
        return jsonify(respDict)


api.add_resource(RobotAPI, '/qa', endpoint='qa')


if __name__ == "__main__":
    # app.debug = True
    app.run()
</code>

实现了想要的效果:

输入一段文字,格式是:

play a xxx song

然后内部连接mongo去find到对应的audio文件,并返回对应的信息:

期间还打印出其他的搜到的文件:

转载请注明:在路上 » 【已解决】Flask中连接远程MongoDB数据库的gridfs并返回查询到的文件数据

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
14 queries in 0.235 seconds, using 10.37MB memory