I'm trying to abstract my sqlalchemy query call, the complete unmodified call looks like this:
Session.query(User).options(FromCache('redis1')).filter(User.id == user_id).all()
The dynamic parts I need control over is User, redis1 and the last call all() I want to call something like above line with the possibility to change the things in bold above in the arguments.
My first try turned out like this:
# Abstracts the final chained method
def q(obj, action):
return getattr(obj, action)()
# Removes a lot of boiler plate code
# but doesn't give me control over the cache argument
# which I need in the same method as the action above
def query(model):
return Session.query(model).options(FromCache('redis1'))
# Called like this
result = q(query(User).filter(User.id == user_id), 'all')
But I'd obviously only want one function instead of two so I can control both the action and the model. The reason for this is that I'd like to wrap the .one() or .all() call in a try-except block that will go through different cache servers in the FromCache option in case the query fails. But doing this every time I write a query would be annoying.
I'm looking for something like this (code doesn't work, obviously):
def q(model, filters, action):
data = None
servers = ['redis1', 'redis2']
for server in servers:
try:
call = Session.query(model).options(FromCache(redis)).filters_here_somehow()
data = getattr(call, obj)() # Final call from action added
except:
continue
break;
return data
# and called something like this.. (or some other way)
result = q(User, the filter/between/limit/whatnot here, 'all')
Any ideas or am I totally way off base? Or is there a smarter way to do this?