如何知道是否可以禁用 SQLALCHEMY _ TRACK _ MODIFICATES?

每次我运行我的应用程序,使用 Flask-SQLAlchemy 我得到以下警告,SQLALCHEMY_TRACK_MODIFICATIONS选项将被禁用。

/home/david/.virtualenvs/flask-sqlalchemy/lib/python3.5/site-packages/flask_sqlalchemy/__init__.py:800: UserWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True to suppress this warning.
warnings.warn('SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future.  Set it to True to suppress this warning.')

我试图找出这个选项的作用,但是 Flask-SQLAlchemy 文档并不清楚这个跟踪的用途。

SQLALCHEMY_TRACK_MODIFICATIONS

如果设置为 True (默认值) ,Flask-SQLAlchemy 将跟踪对象的修改并发出信号。这需要额外的内存,如果不需要可以禁用。

我怎样才能知道我的项目是否需要 SQLALCHEMY_TRACK_MODIFICATIONS = True,或者我是否可以安全地禁用这个功能并节省服务器上的内存?

119643 次浏览

您的应用程序很可能不使用 Flask-SQLAlchemy 事件系统,因此您可能是安全的。您需要审计代码来验证——您正在寻找任何连接到 ABC0或 before_models_committed的东西。如果您确实发现正在使用 Flask-SQLAlchemy 事件系统,那么您可能应该更新代码以使用 SQLAlchemy 的内置事件系统。

Flask-SQLAlchemy 2.1的默认值是 None,这是一个假值,因此事件系统是 被关闭了。在旧版本中,默认值是 True,因此需要显式禁用它。

但是,在这两种情况下,警告在显式设置为 False之前都不会消声:

SQLALCHEMY_TRACK_MODIFICATIONS = False

到你的应用程序配置。


背景——以下是警告告诉你的:

Flask-SQLAlchemy 有自己的事件通知系统,该系统位于 SQLAlchemy 之上。为此,它跟踪对 SQLAlchemy 会话的修改。这需要额外的资源,因此选项 SQLALCHEMY_TRACK_MODIFICATIONS允许您禁用修改跟踪系统。

这一变化的理由有三:

  1. 没有多少人使用 Flask-SQLAlchemy 的事件系统,但是大多数人没有意识到禁用它可以节省系统资源。所以更明智的做法是禁用它,希望使用它的人可以打开它。

  2. Flask-SQLAlchemy 的事件系统有很多漏洞(见下面提到的 pull 请求中的问题) ,需要对一个很少人使用的特性进行额外的维护。

  3. 在 v0.7中,SQLAlchemy 本身添加了一个 强大的事件系统,其中包括创建自定义事件的能力。理想情况下,Flask-SQLAlchemy 事件系统只需创建一些自定义 SQLAlchemy 事件钩子和侦听器,然后让 SQLAlchemy 自己管理事件触发器。

您可以在关于 开始触发此警告的 pull 请求的讨论中看到更多内容。

Jeff Widman 的详细解释非常完美。

因为我有一些复制和粘贴战斗之前得到这个权利,我想让它更容易为下一个将在我的鞋子。

必须在代码中添加所需的配置:

app = Flask(__name__)

以及:

db = SQLAlchemy(app)

如果要启用跟踪修改,请添加:

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

否则,如果你是 没有使用这个特性,你可能想改变值为 False:

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

由于您在配置中显式设置了参数,因此这将使警告无效。

最后的结果应该类似于这个例子:

from flask import Flask


app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False


db = SQLAlchemy(app)

注意
请记住,目前(二零二二年七月) SQLALCHEMY _ TRACK _ MODIFICATION 默认为 没有,因此如果您不配置它,就会出现与 没有失忆的风险相关的内容。
无论如何,如果要禁止显示警告,必须在配置中选择 True 和 False。

感谢 Jeff Widman 提供的建议和细节。

以上答案看起来不错。但是,我想在 Flask-SQLAlchemy 文档中指出这一行,因为在应用程序配置中设置 SQLALCHEMY_TRACK_MODIFICATIONS = False之后,仍然会收到这些警告。

在这一页: http://flask-sqlalchemy.pocoo.org/2.3/config/

Flask-SQLAlchemy 存在以下配置值。Flask-SQLAlchemy 从主 Flask 配置中加载这些值,可以通过各种方式填充它们。请注意,其中一些在引擎创建后无法修改,因此请确保尽早进行配置,并且不要在运行时修改它们。

换句话说,确保设置 app.config 之前以创建 Flask-SQLAlchemy 数据库。

例如,如果将应用程序配置为设置 SQLALCHEMY_TRACK_MODIFICATIONS = False:

from flask import Flask
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False


db = SQLAlchemy(app)

在将应用程序传递给 SqlAlchemy 之前,一定要设置应用程序配置属性。下面是设置到 sql 服务器的连接的示例。

import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy


SECRET_KEY = os.urandom(32)
SERVER = 'MY_DB_SERVER'
DATABASE = 'MY_DB_NAME'
USERNAME = 'MY_DOMAIN\\MY_USERNAME'
PASSWORD = '$ecretsSecretsarenofun...' # the office ref iykyk
DRIVER = 'SQL SERVER'
DATABASE_CONNECTION = f'MSSQL://{USERNAME}:{PASSWORD}@{SERVER}/{DATABASE}?driver={DRIVER};trusted_connection=yes'


app = Flask(__name__)


# set your config properties BEFORE passing the app to SQLAlchemy
app.config['SECRET_KEY'] = SECRET_KEY
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_CONNECTION
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False


db = SQLAlchemy(app)

2020年的答案

如果您有这样的问题,那么您肯定不需要这个特性。

顺便说一句,顶级答案已经过时了。从版本2.1(2015年10月23日发布)开始,这个配置 SQLALCHEMY_TRACK_MODIFICATIONS默认为 None。这意味着跟踪行为默认为禁用,您不需要担心内存丢失。

除非您对终端警告感到困扰,否则可以通过将其设置为 False来取消该警告:

from flask import Flask


app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False


db = SQLAlchemy(app)

通过复制粘贴到 shell 上解决了这个问题:

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False