SQLAlchemy / Pyramid DBSession刷新问题

时间:2012-10-11 10:29:24

标签: python mysql sqlalchemy pyramid

这是我的情景: 第一个视图呈现表单,数据转到secend视图,我将其存储在DB(MySQL)中并重定向到第三个视图,显示写入db的内容:

Stoing to db:
    DBSession.add(object)
    transaction.commit()

DB Session:
    DBSession = scoped_session(sessionmaker(expire_on_commit=False,
                                            autocommit=False, 
                                            extension=ZopeTransactionExtension()))

之后,当我多次刷新页面时,有时候我会看到DB更改,有时不会,有时候是旧数据,第二次有新数据等等... 当我重新启动服务器(本地,pserve)时,数据库数据是最新的。

也许这是创建会话的问题?

5 个答案:

答案 0 :(得分:0)

检查MySQL的transaction isolation level

InnoDB的默认值为REPEATABLE READ:“同一事务中的所有一致读取读取第一次读取建立的快照。”

您可以在create_engine的调用中指定隔离级别。请参阅SQLAlchemy docs

我建议您尝试READ COMMITTED隔离级别,看看是否能解决您的问题。

答案 1 :(得分:0)

如何缓存?

输出缓存服务器端吗?

浏览器是否显示该页面的旧缓存版本?

答案 2 :(得分:0)

目前尚不清楚您的事务对象到底是什么或它如何连接到SQLAlchemy数据库会话。我在Pyramid文档中看不到有关事务的任何内容,我在代码中看不到任何将事务对象链接到SQLAlchemy会话的内容,因此可能缺少某些配置。您基于此代码的示例是什么?

此外:sessionmaker调用通常在文件分数下完成,以创建单个会话工厂,然后重复使用该工厂来创建来自同一源的会话对象。 "the sessionmaker() function is normally used to create a top level Session configuration which can then be used throughout an application without the need to repeat the configurational arguments."

可能的情况是,由于您正在创建多个会话工厂,因此存在一些应该跨会话共享但实际上不共享的数据,因为每个工厂创建一次。试试just calling sessionmaker once,看看是否有所作为。

答案 3 :(得分:0)

我相信你的问题很可能是一个持久的会议。默认情况下,Pyramids在提交后会使会话中的所有对象失效 - 这意味着SQLA将在您下次需要时从数据库中获取它们,并且它们将是新鲜的。

您已通过指示“expire_on_commit = False”覆盖此默认值 - 因此,如果您打算让该会话对象在后续请求中获取新数据,请确保在提交更改后调用session.expire_all()。 (对于Pyramid中的多个请求,会话对象是相同的,但是您不能保证获得相同的线程范围会话)我建议不要在提交时将expire设置为false,或者使用非全局会话:请参阅{{3 }}

或者,您可以确保在必要时使对象过期,因为知道未过期的对象将以它们的方式保留在内存中并且不会刷新,并且可能与不同线程范围的会话中的同一对象不同。 / p>

答案 4 :(得分:0)

问题是您正在设置expire_on_commit=False。如果你删除它,它应该工作。您可以详细了解它在http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html#sqlalchemy.orm.session.Session.commit

上的作用