首页 > 解决方案 > Flask 和 Flask-PyMongo “用户警告:MongoClient 在分叉前打开。”

问题描述

我正在使用 MongoDB 数据库开发 Flask 应用程序。

我将该数据库用于我的核心应用程序数据以及 Flask-Dance 令牌存储 ( https://flask-dance.readthedocs.io/en/latest/storages.html )。自定义存储后端的代码在token_storages.py下面。

Flask 开发服务器中的一切都运行良好,但是当我尝试通过 uWSGI 运行我的 prod 服务器时,我收到此错误:

UserWarning: MongoClient opened before f
ork. Create MongoClient only after forking. See PyMongo's documentation for details: https://pymongo.readthedocs.io/en/stable/faq.html#is-
pymongo-fork-safeUserWarning: MongoClient opened before f
ork. Create MongoClient only after forking. See PyMongo's documentation for details: https://pymongo.readthedocs.io/en/stable/faq.html#is-
pymongo-fork-safe

我看到的所有研究都是指connect=False实例化 PyMongo 时的设置,但这没有任何效果。根据文档,此设置应为默认设置(https://flask-pymongo.readthedocs.io/en/latest/)。

该错误实际上并没有告诉我哪里出了问题——任何关于如何找到 PyMongo 认为错误的指导将不胜感激。

我能找到的所有数据库调用都是在 Flask 路由中进行的,我相信这应该可以正常工作(请参见storyboard_routes.py下面的示例。

我相信下面的代码应该足以提供有关应用程序构建的详细信息,但如果还应包含其他内容,请告诉我。

最后,我确实发现lazy-apps = true我的 uWSGI 设置中的设置确实解决了这个问题(在 中wsgi.ini),但如果可能的话,我宁愿解决根本问题。

提前致谢!

这是建议的,但至少在今天它是不准确的,因为 connect=true 不是当前的默认值。尽管如此,我还是尝试了它,但没有成功。 MongoClient 在 fork 之前打开。仅创建 MongoClient Flask

相关版本

Python 3.8.10 pymongo 3.12.0 Flask-PyMongo 2.3.0 Flask 2.0.1 Flask-Dance 5.0.0 </p>

我的应用程序/初始化.py

from flask import Flask
from flask_session import Session  # https://pythonhosted.org/Flask-Session
from . import app_config
from .util import misc
from .routes import graph_auth_routes
from .routes import google_auth_routes
from .routes import storyboard_routes
from .db import init_db

def create_app():
    app = Flask(__name__)
    app.config.from_object(app_config)
    azure_oauth = misc.create_azure_dance_blueprint(app)
    google_oauth = misc.create_google_dance_blueprint(app)
    app.config['MONGO_CONNECT'] = False # This has no effect since already the default

    init_db(app)
    Session(app)
    app.register_blueprint(graph_auth_routes.bp)
    app.register_blueprint(google_auth_routes.bp)
    app.register_blueprint(storyboard_routes.bp)
    return app

app=create_app()

我的应用程序/db.py

from flask_pymongo import PyMongo

mongo = PyMongo()

def init_db(app):
    print("Initializing DB")
    mongo.init_app(app)
    return app

my_app/util/token_storages.py

from flask import session
from flask_dance.consumer.storage import BaseStorage
from ..db import mongo


class MongoStorage(BaseStorage):
    def __init__(self, oauth_provider):
        self.oauth_provider = oauth_provider

    def get(self, blueprint):
        print("getting token")
        try:
            token = mongo.db["tokens"].find_one(
                {
                    "contact_id": session["contact_id"],
                    "oauth_provider": self.oauth_provider,
                }
            )["oauth"]["token"]
            return token
        except:
            print("can't find token for %s" % self.oauth_provider)
            return None

    def set(self, blueprint, token):
        print("setting token")
        query = mongo.db["tokens"].update_one(
            {
                "contact_id": session["contact_id"],
                "oauth_provider": self.oauth_provider,
            },
            {"$set": {"oauth.token": token, "oauth_provider": self.oauth_provider}},
            upsert=True,
        )

    def delete(self, blueprint):
        print("deleting token")
        mongo.db["tokens"].delete_one(
            {
                "contact_id": session["contact_id"],
                "oauth_provider": self.oauth_provider,
            }
        )
        return None

my_pp/routes/storyboard_routes.py

@bp.route("/page2_365")
@misc.default_error_handler
def page2_365():
    # Update if Google integration was performed
    if request.args.get("gc_integration"):
        filter = {"_id": session["contact_id"]}
        new_value = {
            "$set": {"gc_integration": misc.str2bool(request.args["gc_integration"])}
        }
        mongo.db["contacts"].update_one(filter, new_value)

wsgi.ini

[uwsgi]
module = lead_wizard:app
master = true
processes = 5
workers=1
socket = /tmp/lead_wizard.sock
chmod-socket = 666
vacuum = true
die-on-term = true

标签: pythonflaskpymongoflask-pymongoflask-dance

解决方案


推荐阅读