Может кто-нибудь объяснить, как я могу избежать зависания приложения, когда у меня, например, есть список сущностей и возможность переходить на страницы с подробностями.
Итак, я открываю список, и начинается один сеанс sqlalchemy, затем я открываю одну страницу с подробностями, а затем - другую, затем еще одну и приложение замораживается, потому что один сеанс блокирует другой.
Я не могу использовать один сеанс для всего приложения, потому что тогда я не могу сказать, что что-то было отредактировано в форме, просто проверяя session.dirty, новые, удаленные атрибуты и обработка состояния приложения становится адом хрупкого нечитаемого кода.
Нужно ли реализовывать какую-то другую политику обработки сеансов?
Нужно ли настраивать sqlalchemy mapping или sql server?
Вот минимальный рабочий пример:
from sqlalchemy import MetaData, Table, Column, FetchedValue, ForeignKey, create_engine
from sqlalchemy.types import BigInteger, String
from sqlalchemy.orm import mapper, relationship, sessionmaker, Session
class Ref(object):
id = None
name = None
id_parent = None
class TableMapper(object):
def __init__(self, metadata, mapped_type):
self._table = None
self._mapped_type = mapped_type
def get_table(self):
return self._table
def set_table(self, table):
assert isinstance(table, Table)
self._table = table
class RefTableMapper(TableMapper):
def __init__(self, metadata):
TableMapper.__init__(self, metadata, Ref)
self.set_table(Table('Ref', metadata,
Column('id', BigInteger,
primary_key = True, nullable = False),
Column('name', String),
Column('id_parent', BigInteger,
ForeignKey('Ref.id'))
))
def map_table(self):
r_parent = relationship(Ref,
uselist = False,
remote_side = [self._table.c.id],
primaryjoin = (
self._table.c.id_parent == self._table.c.id))
mapper(Ref, self._table,
properties = {'parent': r_parent})
return self._table
class Mapper(object):
def __init__(self, url, echo = False):
self._engine = create_engine(url, echo = echo)
self._metadata = MetaData(self._engine)
self._Session = sessionmaker(bind = self._engine, autoflush = False)
ref_t = RefTableMapper(self._metadata).map_table()
def create_session(self):
return self._Session()
if __name__ == '__main__':
mapp = Mapper(r'mssql://username:pwd@Server\SQLEXPRESS/DBName', True)
s = mapp.create_session()
rr = s.query(Ref).all()
s1 = mapp.create_session()
merged = s1.merge(rr)
merged.flush()
s2 = mapp.create_session()
rr1 = s2.query(Ref).all() #application freezes!