我得到一個頁面的第二刷新以下錯誤: DetachedInstanceError:實例沒有被綁定到會話;屬性刷新操作無法繼續的Python(金字塔架構)是持續的請求之間的數據和我想不通爲什麼
DetachedInstanceError: Instance <MetadataRef at 0x107b2a0d0> is not bound to a Session; attribute refresh operation cannot proceed
- Expression: "result.meta_refs(visible_search_only=True)"
- Filename: ... ects/WebApps/PYPanel/pypanel/templates/generic/search.pt
- Location: (line 45: col 38)
- Source: ... meta_ref result.meta_refs(visible_search_only=True)" tal:omi ...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Arguments: repeat: {...} (0)
renderer_name: templates/home.pt
models: <list - at 0x1069e4d88>
results: <list - at 0x107c30d40>
renderer_info: <RendererHelper - at 0x1069b5650>
active_models: <list - at 0x107b69050>
query:
pagination: <NoneType - at 0x104dd5538>
req: <Request - at 0x107b4e690>
title: <NoneType - at 0x104dd5538>
generic: <NoneType - at 0x104dd5538>
request: <Request - at 0x107b4e690>
context: <RootFactory - at 0x107b12090>
page: 1
view: <Page - at 0x107b128d0>
這個問題似乎是請求之間緩存數據的一些共享。問題是,它應該只是一個本地緩存(即重新查詢一切爲了下一個請求)
模板的相關部分是:
<div tal:repeat="meta_ref result.meta_refs(visible_search_only=True)" tal:omit-tag="True">
<div tal:define="meta result.meta(meta_ref.key, None)" tal:condition="meta is not None">
<div>${meta_ref.name} = ${meta}</div>
</div>
</div>
我DBSession只聲明瞭一次,在模型的.py(如果有差別):
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
如果我停下緩存它修復它,這意味着我只需要提出要求,我不知道該怎麼辦之間就沒有緩存。
這是我meta_refs功能:
def meta_refs(self, visible_only=False, visible_search_only=False):
model = self.__class__.__name__
if Base._meta_refs is None:
Base._meta_refs = {}
try:
for result in DBSession.query(MetadataRef):
if result.model not in Base._meta_refs:
Base._meta_refs[result.model] = []
Base._meta_refs[result.model].append(result)
except DBAPIError:
pass
if model not in Base._meta_refs:
return []
results = []
for result in Base._meta_refs[model]:
#@TODO: Remove temporary workaround
if inspect(result).detached:
Base._meta_refs = None
return self.meta_refs(visible_only, visible_search_only)
#END of workaround
if visible_only and result.visible is False:
continue
if visible_search_only and result.visible_search is False:
continue
results.append(result)
return results
另外值得一提的是,元()函數還緩存,並沒有同樣的問題 - 我想可能是關鍵的區別是它一個緩存字符串的字典而不是ORM對象。
我使用pserve服務於它,而我正在開發它(如果也有差別)
的臨時解決方法,在我的代碼,使用sqlalchemy.inspect,工作,但我真的只是想數據只是不會持久化(即Base._meta_refs在我第一次訪問它時100%應該等於None)。
任何人有任何想法?如果這是在請求之間緩存的,我相信還有其他的東西也是如此,並且這對於意外行爲來說太有可能了。
雖然我所有的簡單化,我需要通過一個SQL語句(不希望他們的請求之間持續存在)中的所有數據。 ..檢索所有行需要4.3ms平均值或平均值爲3.8ms,以便爲單個模型檢索它們,因此如果我檢索多個對大多數請求都必需的模型,則效率低下。行是微小的順便說一句,這有所不同。 無論如何,我會如何將數據存儲在請求對象中?這聽起來是可行的,但我似乎無法找到像這樣的文件。 –
我不知道你服務一次請求時需要MetadataRef不止一個模型,但我的觀點是,你的代碼是什麼,似乎在做太複雜。 SQLAlchemy的查詢是很好的工具,沒有理由避免使用它來支持循環和「手動」過濾。 –
無論如何,你的問題的答案是在我原來的職位的第一句話。請隨時忽略其餘部分。 –