Python 使用 Flask 时持久数据库连接的最佳实践
Best practices for persistent database connections in Python when using Flask
我的问题是关于在生产环境或其他关注性能的环境中使用 Flask 时处理数据库连接的推荐方法。在 Flask 中,g 对象可用于存储东西,打开的数据库连接可以放在那里,以允许应用程序在同一请求期间的后续数据库查询中重用它们。但是,g 对象不会跨请求持续存在,因此似乎每个新请求都需要一个新的数据库连接(以及随之而来的性能损失)。
我在这个问题上发现的最相关的问题是:How to preserve database connection in a python web server 但答案只提出了连接池的抽象概念(没有将它与人们如何在 Flask 中使用它以及如何使用它联系起来)跨请求生存)或提出仅与一种特定类型的数据库或特定堆栈相关的解决方案。
所以我的问题是关于在 Flask 上构建连接到 任何 种数据库的生产应用程序时应该采用的一般方法。似乎涉及连接池的东西是正确的方向,特别是因为它适用于传统的 Python 应用程序。但我想知道在使用 Flask 时推荐的方法是什么,因为前面提到的跨连接持久性问题,以及生产中的 Flask 应用程序 运行 来自 WSGI 服务器的事实,这可能会增加更多的复杂性。
编辑:基于推荐 flask sqlalchemy 的评论。假设 flask sqlalchemy 解决了这个问题,它是否也适用于 Neo4J 或者 Flask 应用程序使用的任何任意数据库?许多现有的数据库连接器已经原生支持池化,那么为什么要引入一个主要目的是提供 ORM 功能而不是连接管理的附加依赖项呢?另外,sqlalchemy 如何解决跨请求持久化的基本问题?
事实证明,有一种直接的方法可以实现我所追求的目标。但正如评论者所建议的那样,如果完全有可能走 flask sqlalchemy 路线,那么你可能想走那条路。我解决该问题的方法是将连接对象保存在模块级变量中,然后根据需要导入该变量。这样,它就可以在 Flask 内部和其他模块中使用。这是我所做的简化版本:
app.py
from flask import Flask
from extensions import neo4j
app = Flask(__name__)
neo4j.init_app(app)
extensions.py
from neo4j_db import Neo4j
neo4j = Neo4j()
neo4j_db.py
from neo4j import GraphDatabase
class Neo4j:
def __init__(self):
self.app = None
self.driver = None
def init_app(self, app):
self.app = app
self.connect()
def connect(self):
self.driver = GraphDatabase.driver('bolt://xxx')
return self.driver
def get_db(self):
if not self.driver:
return self.connect()
return self.driver
example.py
from extensions import neo4j
driver = neo4j.get_db()
从这里开始,驱动程序 将包含将在 Flask 请求中持续存在的数据库驱动程序。
希望对遇到同样问题的人有所帮助。
我的问题是关于在生产环境或其他关注性能的环境中使用 Flask 时处理数据库连接的推荐方法。在 Flask 中,g 对象可用于存储东西,打开的数据库连接可以放在那里,以允许应用程序在同一请求期间的后续数据库查询中重用它们。但是,g 对象不会跨请求持续存在,因此似乎每个新请求都需要一个新的数据库连接(以及随之而来的性能损失)。
我在这个问题上发现的最相关的问题是:How to preserve database connection in a python web server 但答案只提出了连接池的抽象概念(没有将它与人们如何在 Flask 中使用它以及如何使用它联系起来)跨请求生存)或提出仅与一种特定类型的数据库或特定堆栈相关的解决方案。
所以我的问题是关于在 Flask 上构建连接到 任何 种数据库的生产应用程序时应该采用的一般方法。似乎涉及连接池的东西是正确的方向,特别是因为它适用于传统的 Python 应用程序。但我想知道在使用 Flask 时推荐的方法是什么,因为前面提到的跨连接持久性问题,以及生产中的 Flask 应用程序 运行 来自 WSGI 服务器的事实,这可能会增加更多的复杂性。
编辑:基于推荐 flask sqlalchemy 的评论。假设 flask sqlalchemy 解决了这个问题,它是否也适用于 Neo4J 或者 Flask 应用程序使用的任何任意数据库?许多现有的数据库连接器已经原生支持池化,那么为什么要引入一个主要目的是提供 ORM 功能而不是连接管理的附加依赖项呢?另外,sqlalchemy 如何解决跨请求持久化的基本问题?
事实证明,有一种直接的方法可以实现我所追求的目标。但正如评论者所建议的那样,如果完全有可能走 flask sqlalchemy 路线,那么你可能想走那条路。我解决该问题的方法是将连接对象保存在模块级变量中,然后根据需要导入该变量。这样,它就可以在 Flask 内部和其他模块中使用。这是我所做的简化版本:
app.py
from flask import Flask
from extensions import neo4j
app = Flask(__name__)
neo4j.init_app(app)
extensions.py
from neo4j_db import Neo4j
neo4j = Neo4j()
neo4j_db.py
from neo4j import GraphDatabase
class Neo4j:
def __init__(self):
self.app = None
self.driver = None
def init_app(self, app):
self.app = app
self.connect()
def connect(self):
self.driver = GraphDatabase.driver('bolt://xxx')
return self.driver
def get_db(self):
if not self.driver:
return self.connect()
return self.driver
example.py
from extensions import neo4j
driver = neo4j.get_db()
从这里开始,驱动程序 将包含将在 Flask 请求中持续存在的数据库驱动程序。
希望对遇到同样问题的人有所帮助。