簡體   English   中英

使用sqlalchemy延遲更改

[英]Delayed change using sqlalchemy

我在多進程環境中面臨着奇怪的行為。

我的第一個進程(后來稱為P1)通過sqa寫入db。 我的第二個進程(后來稱為P2)通過sqa從db讀取。 第二個過程是一個Web應用程序,該應用程序要求通過ajax調用獲取最新數據。

當P1更新數據(寫)時,P2不會立即看到更改(讀)。 它必須先輪詢幾次,然后才能實際看到數據庫更改(issuing session.query(...)) 如果我運行另一個P3進程,則可以看到實際上是在db中完成的更改,但是P2(Web應用程序)沒有立即看到它。

我在Ubuntu 13.04上運行sqa 0.8.4 (underlying db: sqlite) ,並且我的Web應用程序基於cherrypy framework (3.2.0)

SQLAlchemy文檔中所述,我使用作用域會話來獲取線程安全的會話對象

這是我所有進程使用的OrmManager類:

class OrmManager:

    def  __init__(self, database, metadata, echo=False):
        self.database = database

        engine = create_engine('sqlite:///' + database,
                               echo=echo,
                               connect_args={'detect_types': sqlite3.PARSE_DECLTYPES|
                                              sqlite3.PARSE_COLNAMES},
                               native_datetime=True,
                               poolclass=NullPool,
                               convert_unicode=True
                           )

    metadata.create_all(engine)

    # this factory is thread safe: a session object is returned (always the same) to the
    # caller. If called from another thread, the returned session object will be different
    session_factory = sessionmaker(bind=engine, expire_on_commit=False)
    self.session = scoped_session(session_factory)

def get_session(self):

    session = self.session()
    return session

P1,P2和P3實現OrmManager並使用返回的會話,如下所示:

orm_mgr = OrmManager(database=<path/to/my/.sqlite/file>, metadata=METADATA)

session = orm_mgr.get_session()

# do some stuff here

session.commit()

我檢查了P1代碼。 數據庫更改已(call to session.commit())但與P3 (cmd line process)相比, P2 (web app)無法實時看到更改。 P2可能需要幾秒鍾才能獲得更改...

有任何想法嗎 ?

非常感謝,

皮埃爾

找到了問題。 根據SQLAlchemy文檔,必須在每個Web請求之后調用Session.remove()。

我將以下代碼添加到我的cherrypy應用程序:

def on_end_request():
    """As mentioned in SQLAlchemy documentation,
    scoped_session .remove() method has to be called
    at the end of each request"""

    Session.remove()

和:

cherrypy.config.update({'tools.dbsession_close.on' : True})

# As mentioned in SQLAlchemy documentation, call the .remove() method
# of the scoped_session object at the end of each request
cherrypy.tools.dbsession_close = cherrypy.Tool('on_end_request', on_end_request)

現在工作正常。

還有其他人

皮埃爾

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM