簡體   English   中英

如何以持久和線程安全的方式處理大型 Flask 項目中的 MongoDB 連接?

[英]How to handle a MongoDB connection in a large Flask project in a persistent and thread-safe manner?

我有一個跨多個模塊的大型Flask項目。 我希望所有這些模塊都能訪問我的 MongoDB ( PyMongo ) 數據庫連接。 根據最佳實踐,正是我想要一個連接池的整個應用程序(即在所有模塊)堅持。

不可行的解決方案(來自其他相關的 StackOverflow 答案)

  1. 我無法創建全局變量並將其傳遞給我調用的每個模塊,因為這不是線程安全的(尤其是當我的db對象不是只讀時)。 示例如下。
  2. 我無法為每個請求創建一個新連接,因為這樣效率低下。
  3. 我不能使用Flask.g “全局”變量,因為它會隨着每個請求而被Flask.g ,使其本質上等同於第 2 點。
  4. 我不能簡單地將數據庫連接代碼放入一個新模塊(如config.py )並在需要時從其他模塊調用它,因為這樣我每次從不同模塊調用它時都會創建新連接。

問題

  1. 如何以線程和進程安全的方式創建單個持久的MongoDB 連接?
  2. 我如何跨模塊訪問這個? 換句話說,如何使其跨模塊全局化?
  3. 對此沒有最佳實踐嗎? 文獻要么過時,要么不存在。 請回答 MongoDB(如果可能,特別是 PyMongo)。

例子

這是我將如何創建全局變量並跨模塊使用它的最小工作示例(Infeasible Solutions 中的第 1 點)。

主文件

from module1 import helper_function

app = Flask(__name__)
db = new_db_connection()

@app.route('/page1'):
def page1():
    db_return = db.query1()
    db.cache = new_value # this makes this entire code thread-unsafe
    return db_return

@app.route('/page2'):
def page2():
    db_return = db.query2()
    db_return2 = helper_function(db) # doesn't seem right that I have to pass this object around all the time
    return db_return

模塊1.py

def helper_function(db):
    db_return = db.query3()
    return db_return

我一直在同一條船上,我想出的答案是向每個函數傳遞一個參數。 如果有更好的方法,我很想知道。

而不是傳遞 db 值,我實際上傳遞了一個自定義上下文對象,該對象具有 mongoclient db 以及一堆其他有用的方法(例如記錄結果 ID 等)。

class Context:

    def __init__(self, cs: str = None) -> None:
        self.cs = cs

        try:
            self.db = pymongo.MongoClient(self.cs).get_database()
        except Exception as e:
            raise ValueError(f'Failed to connect to server using connection string {self.cs}')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM