如何禁用SQLAlchemy缓存?

Zey*_*Fan 15 python mysql innodb sqlalchemy

我使用时遇到缓存问题sqlalchemy.

sqlalchemy用来将数据插入MySQL数据库.然后,我有另一个应用程序处理这些数据,并直接更新它.

sqlalchemy始终返回旧数据而不是更新数据.我想sqlalchemy缓存了我的请求......所以......我应该如何禁用它?

zzz*_*eek 40

人们认为游戏中存在"缓存"的通常原因是,除了通常的事务本地SQLAlchemy身份映射之外,他们正在观察事务隔离的影响.默认情况下,SQLAlchemy的会话在事务模式下工作,这意味着它等待直到session.commit()被调用以便将数据持久保存到数据库中.在此期间,其他正在进行的其他交易将无法查看此数据.

但是,由于交易的孤立性,还有一个额外的转折点.正在进行的其他事务在提交之前不仅不会看到事务的数据,在它们被提交或回滚之前它们也无法在某些情况下看到它(这与close()在此处的效果相同) .具有平均隔离程度的事务将保持到目前为止已加载的状态,并且即使实际数据已更改,也会继续为事务提供相同的本地状态 - 这在事务隔离用语中称为可重复读取.

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

  • “SQLAlchemy 的会话默认以事务模式工作” --- 您能给我们展示一种停止默认模式的方法吗?我不需要解释,只想要 1 行代码来完全禁用事务。特别是对于愚蠢的 SELECT 调用。 (2认同)
  • 实际上 SQLAlchemy 中有缓存(至少现在是 2021 年)。我使用“session.execute”命令遇到了这个问题。您可以在此处找到有关缓存的信息(在页面上搜索“自缓存以来”字符串)https://github.com/sqlalchemy/sqlalchemy/blob/master/doc/build/core/connections.rst (2认同)
  • @AnarSalimkhanov 不过请注意,您所指的缓存只是一个*语句编译缓存*。从您的链接文档来看:它*“正在缓存仅传递到数据库的**SQL字符串**,而不是查询返回的数据**。它绝不是数据缓存,不会影响为特定 SQL 语句返回的结果也不意味着与获取结果行相关的任何内存使用。"* (2认同)

Nic*_*ams 15

这个问题对我来说真的很令人沮丧,但我终于明白了.

我有一个Flask/SQLAlchemy应用程序与旧的PHP站点一起运行.PHP站点将写入数据库,SQLAlchemy不会知道任何更改.

我尝试了sessionmaker设置autoflush = True失败了我在查询和NONE工作之前尝试了db_session.flush(),db_session.expire_all()和db_session.commit().仍显示陈旧数据.

最后,我遇到了SQLAlchemy文档的这一部分:http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#transaction-isolation-level

设置isolation_level非常有效.现在我的Flask应用程序正在与PHP应用程序"交谈".这是代码:

engine = create_engine(
    "postgresql+pg8000://scott:tiger@localhost/test",
    isolation_level="READ UNCOMMITTED"
)
Run Code Online (Sandbox Code Playgroud)

当使用"READ UNCOMMITED"isolation_level启动SQLAlchemy引擎时,它将执行"脏读",这意味着它将直接从数据库读取未经修改的更改.

希望这可以帮助


这是一个可能的解决方案由AaronD在评论中提供

from flask.ext.sqlalchemy import SQLAlchemy

class UnlockedAlchemy(SQLAlchemy):
    def apply_driver_hacks(self, app, info, options):
        if "isolation_level" not in options:
            options["isolation_level"] = "READ COMMITTED"
    return super(UnlockedAlchemy, self).apply_driver_hacks(app, info, options)
Run Code Online (Sandbox Code Playgroud)

  • 我的代码中只有这样: `class UnlockedAlchemy(SQLAlchemy): def apply_driver_hacks(self, app, info, options): if not "isolation_level" in options: options["isolation_level"] = "READ COMMITTED" return super(UnlockedAlchemy ,自我)。apply_driver_hacks(应用程序,信息,选项)` (2认同)
  • 这根本不符合逻辑。如果更新数据库的事务已正确提交(由 php 站点),为什么需要将隔离级别设置为“READ UNCOMMITTED”?这更像是 PHP 站点如何更新数据库的问题。 (2认同)