简单的代码如:
import pickle, cPickle
from app import session, redis
class MyObj(DeclarativeBase):
@classmethod
def get(cls,id):
key = cls.__name__+":"+str(id)
cached = redis.get(key)
if cached:
# unserialize to cls instance
return cPickle.loads(cached)
record = session.query(cls).filter(cls.id==id).one()
if record:
# serialize and store to redis
redis.set(key, pickle.dumps(record))
return record
# first time , a normal orm instance returned from session query (uncached)
obj = MyObj.get(1)
# but the next requests, get cached from redis.
# and i want to delete the record
delobj = MyObj.get(1)
session.delete(delobj)
session.commit()
它会引发错误,例如"实例xxx不会持久存在"
我在删除之前尝试了session.add(delobj),Pending状态为True(state = inspect(delobj)),但它仍然无法删除。
答案 0 :(得分:0)
您需要merge缓存的实例到当前会话:
merge()
将状态从外部对象传输到会话中的新实例或现有实例。
来自例子:
应用程序将对象存储在内存缓存中,同时由许多
Session
个对象共享。每次从缓存中检索对象时,都会使用merge()
,以便在请求它的每个Session中创建它的本地副本。缓存的对象保持分离状态;只有它的状态被移动到各个Session对象本地的副本中。在缓存用例中,通常使用
load=False
标志来消除协调对象状态与数据库的开销。还有一个名为merge()
的{{1}}“批量”版本,旨在使用缓存扩展的查询对象 - 请参阅Dogpile Caching部分。
所以:
merge_result()
请记住仅缓存 if cached:
# unserialize to cls instance
return session.merge(cPickle.loads(cached), load=False)
的持久对象,否则您将收到错误:
cls
产生上述错误的简单方法:
InvalidRequestError: merge() with load=False option does not support objects transient (i.e. unpersisted) objects. flush() all changes on mapped instances before merging with load=False.
另一方面,如果您首先正确地保留对象:
obj = MyObj()
cached = pickle.dumps(obj)
obj2 = session.merge(pickle.loads(cached), load=False)
...
InvalidRequestError: merge() with load=False option does not support objects transient (i.e. unpersisted) objects. flush() all changes on mapped instances before merging with load=False.