最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Flask中如何用工厂模式初始化pymongo

Flask crifan 1244浏览 0评论
折腾:
【未解决】用蓝图和工厂模式去优化现有Flask项目代码结构
期间,想要把Flask优化代码结构,其中包括转换为工厂模式去初始化Flask的app
其中涉及到PyMongo,而之前的初始化的方式是:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# from flask_pymongo import PyMongo
from gridfs import GridFS
from pymongo import MongoClient
from bson.objectid import ObjectId
 
purePymongo = MongoClient(
    host=app.config["MONGODB_HOST"],
    port=app.config["MONGODB_PORT"],
    username=app.config["MONGODB_USERNAME"],
    password=app.config["MONGODB_PASSWORD"],
    authSource=app.config["MONGODB_AUTH_SOURCE"]
)
log.info("purePymongo=%s", purePymongo)
# mongoServerInfo = purePymongo.server_info()
# log.debug("mongoServerInfo=%s", mongoServerInfo)
 
# Pure PyMongo
gridfsDb = purePymongo.gridfs  # Database(MongoClient(host=['xxx:32018'], document_class=dict, tz_aware=False, connect=True, authsource='gridfs'), 'gridfs')
log.info("gridfsDb=%s", gridfsDb)
fsCollection = GridFS(gridfsDb)  # <gridfs.GridFS object at 0x1107b2390>
log.info("fsCollection=%s", fsCollection)
之后就可以用fsCollection了:
1
2
if fsCollection.exists(audioFileObjectId):
    audioFileObj = fsCollection.get(audioFileObjectId)
但是现在要把Flask换成工厂模式了,则就不清楚是如何初始化了
pymongo flask factory
python – Flask-PyMongo with application factory and blueprints – Stack Overflow
Failing to instantiate PyMongo objects from @app.before_request · Issue #11 · dcrosta/flask-pymongo
Flask-PyMongo — Flask-PyMongo 2.1.0 documentation
flask-example/application.py at master · allisson/flask-example
dcrosta/flask-pymongo: PyMongo support for Flask applications
python – Access Flask instance when using Flask-Script – Stack Overflow
1
2
3
4
5
6
7
def create_app(config_name):
    app = Flask(__name__)
    ....
    return app
 
def create_mongo(app):
    return PyMongo(app)
感觉可以?
但是最外层,没有像:
flask-example/application.py at master · allisson/flask-example
1
2
3
4
5
6
7
8
9
10
11
12
# flask mongoengine
 
db = MongoEngine()
 
# flask mail
mail = Mail()
 
 
def create_app(config_filename):
    app = Flask(__name__)
    app.config.from_object(config_filename)
有db可以去调用了啊
inputlogic/flask-starter: A starter Flask project ready for Heroku, MongoDB and multiple env settings
Failing to instantiate PyMongo objects from @app.before_request · Issue #11 · dcrosta/flask-pymongo
“Thanks for your time on explaining some possible approaches. I took a different approach and defined mongo = PyMongo() at top level in application.py and called mongo.init_app(app) in the factory function.”
好像也是类似的办法,去试试吧
Flask-PyMongo — Flask-PyMongo 2.1.0 documentation
PyMongo 3.7.1 Documentation — PyMongo 3.7.1 documentation
目前先去写成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import os
from flask import Flask
 
import logging
from logging.handlers import RotatingFileHandler
 
# from flask_pymongo import PyMongo
from gridfs import GridFS
from pymongo import MongoClient
 
from flask_cors import CORS
 
 
log = logging.getLogger()
 
 
mongo = MongoClient()
fsCollection = None
 
 
def create_app(config_object):
    global app, log, api, mongo, fsCollection
 
    # app = Flask(__name__)
    # app.config.from_pyfile(config_filename)
    #
    # from yourapplication.views.admin import admin
    # from yourapplication.views.frontend import frontend
    # app.register_blueprint(admin)
    # app.register_blueprint(frontend)
 
    app = Flask(__name__)
    CORS(app)
 
 
    # app.config.from_object('config.DevelopmentConfig')
    # # app.config.from_object('config.ProductionConfig')
 
    app.config.from_object(config_object)
 
    log = create_log(app)
 
    log.debug("after load from object: app.config=%s", app.config)
    log.debug('app.config["DEBUG"]=%s, app.config["MONGODB_HOST"]=%s, app.config["FILE_URL_HOST"]=%s',
              app.config["DEBUG"], app.config["MONGODB_HOST"], app.config["FILE_URL_HOST"])
 
    mongo = create_mongo(app, log)
    log.info("mongo=%s", mongo)
    mongoServerInfo = mongo.server_info()
    log.debug("mongoServerInfo=%s", mongoServerInfo)
 
    fsCollection = create_gridfs_fs_collection(mongo, log)
    log.info("fsCollection=%s", fsCollection)
 
    return app
 
 
def create_log(app):
    logFormatterStr = app.config["LOG_FORMAT"]
    logFormatter = logging.Formatter(logFormatterStr)
 
    fileHandler = RotatingFileHandler(
        app.config['LOG_FILE_FILENAME'],
        maxBytes=app.config["LOG_FILE_MAX_BYTES"],
        backupCount=app.config["LOG_FILE_BACKUP_COUNT"],
        encoding="UTF-8")
    fileHandler.setLevel(logging.DEBUG)
    fileHandler.setFormatter(logFormatter)
    app.logger.addHandler(fileHandler)
    # Note: should NOT set StreamHandler here, otherwise will duplicate debug log
    app.logger.setLevel(logging.DEBUG)  # set root log level
 
    log = app.logger
    log.info("app=%s", app)
    # log.debug("app.config=%s", app.config)
 
    return log
 
 
def create_mongo(app):
    mongo_client = MongoClient(
        host=app.config["MONGODB_HOST"],
        port=app.config["MONGODB_PORT"],
        username=app.config["MONGODB_USERNAME"],
        password=app.config["MONGODB_PASSWORD"],
        authSource=app.config["MONGODB_AUTH_SOURCE"]
    )
    return mongo_client
 
 
def create_gridfs_fs_collection(mongo, log):
    # Pure PyMongo
    gridfs_db = mongo.gridfs  # Database(MongoClient(host=['xxx:32018'], document_class=dict, tz_aware=False, connect=True, authsource='gridfs'), 'gridfs')
    gridfs_fs_collection = GridFS(gridfs_db)  # <gridfs.GridFS object at 0x1107b2390>
    return gridfs_fs_collection
待后续调试才知道是否真正工作。
【总结】
Flask改为工厂模式后,mongo的相关代码如下:
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
import os
 
from conf.app import settings
from factory import create_app
 
app.app_context().push()
if __name__ == "__main__":
    app.run(
        host=settings.FLASK_HOST,
        port=settings.FLASK_PORT,
        debug=settings.DEBUG,
        # use_reloader=False
    )
factory.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import os
from flask import Flask
...
 
from gridfs import GridFS
from pymongo import MongoClient
...
from conf.app import settings
 
from flask import g
 
################################################################################
# Global Variables
################################################################################
# # log = logging.getLogger() #<RootLogger root (WARNING)>
# log = None
# print("log=%s" % log)
#
# # mongo = MongoClient() # MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True)
# mongo = None
# print("mongo=%s" % mongo)
# fsCollection = None #None
# print("fsCollection=%s" % fsCollection)
#
# celery = Celery() #<Celery __main__ at 0x1068d8b38>
# celery = None
# print("celery=%s" % celery)
 
################################################################################
# Global Function
################################################################################
 
def create_app(config_object, init_extensions=True):
    # global log
 
    # app = Flask(__name__) #<Flask 'factory'>
    app = Flask(config_object.FLASK_APP_NAME) #<Flask 'RobotQA'>
    ...
 
    # app.config.from_object('config.DevelopmentConfig')
    # # app.config.from_object('config.ProductionConfig')
 
    app.config.from_object(config_object)
    with app.app_context():
        g.app = app
     
    ...
 
        if init_extensions:
            register_extensions(app)
            log.info("flask app extensions init completed")
 
    return app
 
 
def register_extensions(app):
    # global log, mongo, fsCollection, api, celery
 
    log = g.log
 
    mongo = create_mongo(app)
    g.mongo = mongo
    log.info("mongo=%s", mongo)
    mongoServerInfo = mongo.server_info()
    log.debug("mongoServerInfo=%s", mongoServerInfo)
...
 
    return app
 
...
 
def create_mongo(app):
    # mongo_client = MongoClient(
    #     host=app.config["MONGODB_HOST"],
    #     port=app.config["MONGODB_PORT"],
    #     username=app.config["MONGODB_USERNAME"],
    #     password=app.config["MONGODB_PASSWORD"],
    #     authSource=app.config["MONGODB_AUTH_SOURCE"]
    # )
 
    if settings.MONGODB_AUTH_SOURCE:
        mongo_client = MongoClient(
            host=settings.MONGODB_HOST,
            port=int(settings.MONGODB_PORT),
            username=settings.MONGODB_USERNAME,
            password=settings.MONGODB_PASSWORD,
            authSource=settings.MONGODB_AUTH_SOURCE
        )
    elif settings.MONGODB_USERNAME and settings.MONGODB_PASSWORD:
        mongo_client = MongoClient(
            host=settings.MONGODB_HOST,
            port=int(settings.MONGODB_PORT),
            username=settings.MONGODB_USERNAME,
            password=settings.MONGODB_PASSWORD,
        )
    elif settings.MONGODB_PORT:
        mongo_client = MongoClient(
            host=settings.MONGODB_HOST,
            port=int(settings.MONGODB_PORT),
        )
    elif settings.MONGODB_HOST:
        mongo_client = MongoClient(
            host=settings.MONGODB_HOST,
        )
    else:
        mongo_client = MongoClient()
 
 
    return mongo_client
 
...
然后其他模块:
resources/files.py
调用mongo用g.mongo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import g
mongo = g.mongo
fsCollection = g.fsCollection
 
class GridfsAPI(Resource):
 
    def get(self, fileId, fileName=None):
        # log = app.logger
        log.info("fileId=%s, file_name=%s", fileId, fileName)
 
        fileIdObj = ObjectId(fileId)
        log.info("fileIdObj=%s", fileIdObj)
        if not fsCollection.exists({"_id": fileIdObj}):
     
    ...

转载请注明:在路上 » 【已解决】Flask中如何用工厂模式初始化pymongo

发表我的评论
取消评论

表情

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

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.241 seconds, using 22.25MB memory