在 Flask 应用程序中访问 mongoengine 实例的属性

Accessing the properties of the mongoengine instance in a Flask app

我已经在我的 Flask 应用程序中注册了 flask-mongoengine 扩展程序并对其进行了初始化。

我现在想访问它的 conn 属性 因为我也想做纯 MongoDB 查询。

>> app.extensions
{'csrf': <flask_wtf.csrf.CSRFProtect object at 0x00000213B72AB940>,
 'mail': <flask_mail._Mail object at 0x00000213B72ABCF8>,
 'mongoengine': {
     <flask_mongoengine.MongoEngine object at 0x00000213B72ABDD8>: {
         'app': <Flask 'app'>,
         'conn': MongoClient(host=['xxx'], document_class=dict, tz_aware=False, connect=True, ssl=True, replicaset='Cluster0-shard-0', authsource='admin', retrywrites=True, read_preference=Primary())
     }
  },
  'rq2': <flask_rq2.app.RQ object at 0x00000213B5DE8940>,
  'security': <flask_security.core._SecurityState object at 0x00000213B734EE10>
}

有没有办法访问 conn 属性 而不是非常复杂(且容易出错):

>> list(app.extensions.get('mongoengine').values())[0].get('conn')
MongoClient(host=['xxx'], document_class=dict, tz_aware=False, connect=True, ssl=True, replicaset='Cluster0-shard-0', authsource='admin', retrywrites=True, read_preference=Primary())

flask-mongoengine 是否有访问其属性的方法?

MongoEngine实例has a connection attribute使用那个

您不需要使用app.extensions;这更像是一个内部数据结构,供扩展程序在需要从当前应用程序上下文访问时跟踪自己的状态。

在您自己的代码中,只需保留对您创建的 MongoEngine 实例的引用。 documentation 使用:

db = MongoEngine(app)

db = MongoEngine()
# in an app factory, attach to an app with db.init_app(app)

所以你可以使用:

db.connection

接下来,还有一个 current_mongoengine_instance() utility function 本质上为您提供了与您的代码已经实现的相同的对象。像这样使用它:

from flask_mongoengine import current_mongoengine_instance

current_mongoengine_instance().connection

附带说明:此扩展程序使用 app.extensions 的方式是......过度设计和冗余。源码中的原理是:

# Store objects in application instance so that multiple apps do not
# end up accessing the same objects.

但是多个应用程序已经有单独的app.extensions字典。虽然此方法确实允许您使用多个 mongoengine 连接,但您仍然无法使用此数据结构来区分仅具有当前应用程序上下文的不同连接。 current_mongoengine_instance() 的实现仅进一步说明该扩展没有处理多个连接的适当策略。你只得到 'first' 一个,不管它在无序字典的上下文中意味着什么。 Flask SQLAlchemy 扩展改为使用单个扩展实例通过名为 binds.

的系统管理多个连接

您还可以通过

从您的任何文档 class 访问基础 pymongo.Collection
class MyDocument(Document):
    name = StringField()

MyDocument(name='John').save()

coll = MyDocument._get_collection()
print(coll.find_one({'name': 'John'}))