折腾:
【未解决】用蓝图和工厂模式去优化现有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
1 2 3 4 5 6 7 | def create_app(config_name): app = Flask(__name__) .... return app def create_mongo(app): return PyMongo(app) |
感觉可以?
但是最外层,没有像:
1 2 3 4 5 6 7 8 9 10 11 12 | # flask mongoengine db = MongoEngine() # flask mail mail = Mail() # application factory, see: http://flask.pocoo.org/docs/patterns/appfactories/ def create_app(config_filename): app = Flask(__name__) app.config.from_object(config_filename) |
有db可以去调用了啊
“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.”
好像也是类似的办法,去试试吧
目前先去写成:
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