有人可以解釋一下,我如何避免應用程序凍結,例如,當我有一個實體列表並且能夠移動到詳細頁面時。 因此,我打開列表,然後開始一個sqlalchemy會話,然後打開一個詳細信息頁面,然後另一個詳細信息頁面,另一個詳細信息頁面,另一個詳細信息頁面和應用程序凍結,因爲一個會話會阻止另一個會話。 我不能使用一個會話整個應用程序,因爲我不能說,只是檢查session.dirty,新的,刪除的屬性和應用程序狀態處理變成了脆弱的不可讀代碼的地獄,在窗體上編輯了某些東西。如何處理sqlalchemy的數據庫表格阻止策略?
我是否需要實施一些其他類型的會話處理策略? 我是否需要調整sqlalchemy映射或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:[email protected]\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!