Python 关于在sqlalchemy会话中刷新对象

Python 关于在sqlalchemy会话中刷新对象,python,mysql,session,notifications,sqlalchemy,Python,Mysql,Session,Notifications,Sqlalchemy,嗯,我正在处理一个关于sqlalchemy和对象刷新的疑问 我在我有两个会话的情况下,在两个会话中都查询了相同的对象!。。。由于某些特殊原因,我无法关闭其中一个会话。 我在会话A中修改了对象并提交了更改,但在会话B中,属性是初始属性!没有修改 所以。。。我是否应该实现某种通知系统来传达更改,或者在sqlalchemy中有一种内置的方式来做到这一点。会话B中对象的属性将保留在会话B中第一次查询时的属性。此外,SQLAlchemy不会在其他会话中的对象发生更改时尝试自动刷新它们,我认为尝试创建这样的

嗯,我正在处理一个关于sqlalchemy和对象刷新的疑问

我在我有两个会话的情况下,在两个会话中都查询了相同的对象!。。。由于某些特殊原因,我无法关闭其中一个会话。 我在会话A中修改了对象并提交了更改,但在会话B中,属性是初始属性!没有修改

所以。。。我是否应该实现某种通知系统来传达更改,或者在sqlalchemy中有一种内置的方式来做到这一点。会话B中对象的属性将保留在会话B中第一次查询时的属性。此外,SQLAlchemy不会在其他会话中的对象发生更改时尝试自动刷新它们,我认为尝试创建这样的对象也不明智

您应该积极地将每个会话的生命周期看作数据库中的单个事务。会话需要如何以及何时处理其对象可能过时的事实不是一个可以通过内置于SQLAlchemy(或SQLAlchemy的任何扩展)中的算法来解决的技术问题:这是一个“业务”问题,您必须自己确定解决方案并编写代码。“正确”的回答可能是说这不是问题:如果会话B在启动会话B时使用了数据,那么会话B的逻辑可能是有效的。你的“问题”实际上可能不是问题。这些文档实际上有一个统一的解决方案,但如果你希望得到一个一刀切的解决方案,那么它给出了一个相当严峻的回答

会话通常在逻辑会话开始时构造 可能需要访问数据库的操作

每当会话用于与数据库对话时,它都会启动一个会话 数据库事务在开始通信时立即执行。假设 自动提交标志保留为其建议的默认值False,这 在回滚会话之前,事务仍在进行中, 承诺,或关闭。会话将开始一个新事务,如果 在上一笔交易结束后再次使用;从…起 因此,会话能够有一个生命周期 跨多个事务,但一次只能处理一个事务。我们指的是这些 事务范围和会话范围这两个概念

这意味着SQLAlchemy ORM正在鼓励 开发人员在其应用程序中建立这两个作用域, 不仅包括范围的开始和结束,还包括范围 例如,在这些作用域中,单个会话实例是否应该是本地的 对于函数或方法中的执行流,是否应该是 整个应用程序使用的全局对象,或介于两者之间的某个位置 这两个

开发人员确定此范围的负担是一个方面 SQLAlchemy ORM必须对如何 应该使用数据库。工作单元模式是特定的 一种是随着时间积累变化并定期刷新, 保持内存状态与已知的内存中的内容同步 本地交易。这种模式只有在有意义时才有效 事务作用域已就位

也就是说,你可以做一些事情来改变这种情况:

首先,您可以减少会话保持打开的时间。会话B正在查询对象,然后稍后您将对该对象(在同一会话中)执行某些操作,以使属性保持最新。一种解决方案是在单独的会话中完成第二个操作

另一种方法是使用expire/refresh方法,因为


您可以使用
session.refresh()
立即获取对象的最新版本,即使会话之前已经查询过对象

运行此命令,强制会话更新所选数据库中的最新值:

session.expire_all()

我刚刚遇到这个问题,由于某种原因,现有的解决方案对我不起作用。所做的工作是调用
session.commit()
。调用该函数后,该对象具有来自数据库的更新值。

TL;DR不需要进行会话同步,而是直接在引擎上使用SQLAlchemy核心语法,查看您的任务是否可以合理轻松地进行编码,而无需使用(多个)会话

对于有SQL和JDBC经验的人来说,要了解SQLAlchemy有一个关键的方面,不幸的是,我几个月来没有清楚地看到阅读了多个文档,那就是SQLAlchemy由两个根本不同的部分组成:核心部分和ORM部分。由于ORM文档首先在网站上列出,而且大多数示例都使用类似于ORM的语法,因此如果从SQL/JDBC的角度考虑ORM,您就会投入到使用ORM的过程中,并自行设置错误和混淆。ORM使用自己的抽象层,完全控制实际SQL语句的执行方式和时间。经验法则是,会话的创建和终止成本很低,并且它不应该被重新用于程序流和逻辑中可能导致重新查询、同步或多线程的任何内容。另一方面,核心是直接无刺激SQL,非常类似于JDBC驱动程序。“我发现”中有一个地方“建议”使用Core而不是ORM:

建议在这里直接在连接上执行简单的SQL操作,例如递增计数器或在日志中插入额外的行 桌子。在处理连接时,应该使用核心级别的SQL 操作将被使用;e、 g.SQL表达式语言教程中描述的

尽管如此,使用连接似乎会产生与使用会话相同的副作用:重新查询特定记录会返回与第一次查询相同的结果,即使数据库中记录的内容发生了更改。那么,显然是康涅狄格州
session.expire_all()