2014-01-14 3 views
0

Я столкнулся с странным поведением в многопроцессорной среде.Отложенное изменение с использованием sqlalchemy

Мой первый процесс (далее называемый P1) записывается в db через sqa. Мой второй процесс (позже называемый P2) ​​читается с db через sqa. Этот второй процесс - это веб-приложение, в котором запрашиваются последние данные с помощью вызова ajax.

Когда P1 обновляет данные (запись), P2 не видит немедленное изменение (чтение). Он должен опросить несколько раз, прежде чем фактически увидеть изменение db (issuing session.query(...)). Если я запустил другой процесс P3, я вижу, что изменение действительно выполняется в db, но P2 (веб-приложение) не видит его немедленно.

Я бег SQA 0.8.4 (underlying db: sqlite) на Ubuntu 13.04 и мой веб-приложение основано на cherrypy framework (3.2.0)

Я использовал контекстные сеансы, чтобы получить поточно-сессию объекты, как указан в SQLAlchemy documentation

Вот мой класс 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. Изменение db хорошо зафиксировано (call to session.commit()), но изменение не наблюдается в реальном времени на P2 (web app) по сравнению с P3 (cmd line process). Это может занять секунды для P2, чтобы получить изменения ...

Любые идеи?

Спасибо большое,

Pierre

ответ

0

Найдено вопрос. В соответствии с документацией SQLAlchemy после каждого веб-запроса необходимо вызвать 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) 

отлично работает в настоящее время.

HTH другие люди,

Пьер

Смежные вопросы