如何缓存/记忆我的SQLAlchemy函数?
我正在使用FLask-OAuthlib,并想通过Flask-Cache来做一些缓存或记忆功能。我已经在我的视图中设置了缓存,但在缓存这个函数时遇到了一些问题:
@oauth.clientgetter
@cache.memoize(timeout=86400)
def load_client(client_id):
return DBSession.query(Client).filter_by(client_id=client_id).first()
这个函数第一次运行时(还没有缓存)一切正常,但当它从缓存中获取数据时,出现了一些问题,提示说这是一个无效的客户端。我不确定是缓存的方式不对,还是因为有了@oauth.clientgetter这个装饰器导致缓存出现了问题。没有缓存的时候一切都正常,客户端也是有效的。我尝试过调整函数的位置,但结果还是一样:
class Client(Base):
__tablename__ = 'client'
__table_args__ = {'autoload': True}
user = relationship('User')
@classmethod
@cache.memoize(timeout=86400)
def get_client(cls,client_id):
return DBSession.query(cls).filter_by(client_id=client_id).first()
然后,在我的视图中,我有:
@oauth.clientgetter
def load_client(client_id):
return Client.get_client(client_id)
但这也给出了相同的结果。我使用redis作为我的缓存后端,我的键/值如下:
1) "flask_cache_Pwd2uVDVikMYMDNB+gVWlW"
2) "flask_cache_api.models.Client.get_client_memver"
3) "flask_cache_http://lvho.st:5000/me"
GET flask_cache_Pwd2uVDVikMYMDNB+gVWlW:
"!ccopy_reg\n_reconstructor\np1\n(capi.models\nClient\np2\nc__builtin__\nobject\np3\nNtRp4\n(dp5\nS'_sa_instance_state'\np6\ng1\n(csqlalchemy.orm.state\nInstanceState\np7\ng3\nNtRp8\n(dp9\nS'manager'\np10\ng1\n(csqlalchemy.orm.instrumentation\n_SerializeManager\np11\ng3\nNtRp12\n(dp13\nS'class_'\np14\ng2\nsbsS'class_'\np15\ng2\nsS'modified'\np16\nI00\nsS'committed_state'\np17\n(dp18\nsS'instance'\np19\ng4\nsS'callables'\np20\n(dp21\nsS'key'\np22\n(g2\n(S'Iu6copdawXIQIskY5kwPgxFgU7JoE9lTSqmlqw29'\np23\nttp24\nsS'expired'\np25\nI00\nsbsVuser_id\np26\nL4L\nsVname\np27\nS'Default'\np28\nsV_default_scopes\np29\nS'email'\np30\nsVclient_id\np31\ng23\nsV_redirect_uris\np32\nS'http://localhost:8000/authorized/'\np33\nsVactive\np34\nI1\nsVclient_secret\np35\nS'Vnw0YJjgNzR06KiwXWmYz7aSPu1ht7JnY1eRil4s5vXLM9N2ph'\np36\nsVdescription\np37\nNsb."
GET flask_cache_api.models.Client.get_client_memver:
"!S'+gVWlW'\np1\n."
1 个回答
3
试着把你的装饰器顺序反过来:
@cache.memoize(timeout=86400)
@oauth.clientgetter
def load_client(client_id):
return DBSession.query(Client).filter_by(client_id=client_id).first()
编辑
问题似乎出在一个 Client
对象不能被“序列化”,而 cache.memoize
依赖于对象能否被“序列化”。所以在一种情况下,你会遇到无效客户端的错误(客户端对象在序列化和反序列化的过程中没有“存活”下来),而在另一种情况下,会出现某种缓存错误,这种错误会悄悄地阻止对象被缓存(我不太确定是什么机制导致了这种悄悄处理)。
总之,我觉得你根本不应该尝试把你的客户端对象进行缓存。