Hey there!
Following up on this issue, I am trying to store the results of a SELECT with JOINS into the cache, i.e. a list of items or listing. And I am having trouble with it. This is the error on the log when trying to store the value in the cache:
2019-02-14 12:25:15,494 DEBG 'zato-server1' stdout output:
2019-02-14 12:25:15,493 - ERROR - 134:DummyThread-7 - zato.broker:57 - Could not handle broker msg:`Bunch(action='106420', cache_name='availability', expires_at=0.0, expiry=0.0, is_key_pickled=False, is_value_pickled=True, key='check_in:2017-07-01|check_out:2017-07-10|guests:2|rooms:[]', msg_type='0002', orig_now=1550147115.485663, source_worker_id='1.2.135.ebdfed681387770699df7802', value="(lp1\nccopy_reg\n_reconstructor\np2\n(czato.common.odb.api\nWritableKeyedTuple\np3\nc__builtin__\nobject\np4\nNtRp5\n(dp6\nS'_elem'\np7\ncsqlalchemy.util._collections\nKeyedTuple\np8\n((lp9\nI6\naI1\naI6\naVNormal bedroom with one double bed\np10\naI0\naI1\naVbrown\np11\naV106\np12\naI2\naI9\naF1152\na(S'id'\np13\nS'floor_no'\np14\nS'room_no'\np15\nS'name'\np16\nS'sgl_beds'\np17\nS'dbl_beds'\np18\nS'code'\np19\nS'number'\np20\nS'accommodates'\np21\nVnights\np22\nVtotal_price\np23\ntp24\ntRp25\nsbag2\n(g3\ng4\nNtRp26\n(dp27\nS'_elem'\np28\ng8\n((lp29\nI2\naI1\naI2\naVLarge bedroom with two single and one double beds\np30\naI2\naI1\naVblack\np31\naV102\np32\naI4\naI9\naF1332\nag24\ntRp33\nsbag2\n(g3\ng4\nNtRp34\n(dp35\nS'_elem'\np36\ng8\n((lp37\nI3\naI1\naI3\naVVery large bedroom with three single and one double beds\np38\naI3\naI1\naVwhite\np39\naV103\np40\naI5\naI9\naF1422\nag24\ntRp41\nsba.")`, e:`Traceback (most recent call last):
File "/opt/zato/3.0/code/zato-broker/src/zato/broker/__init__.py", line 52, in on_broker_msg
getattr(self, handler)(msg)
File "/opt/zato/3.0/code/zato-server/src/zato/server/base/worker/cache_builtin.py", line 60, in on_broker_msg_CACHE_BUILTIN_STATE_CHANGED_SET
self._unpickle_msg(msg)
File "/opt/zato/3.0/code/zato-server/src/zato/server/base/worker/cache_builtin.py", line 53, in _unpickle_msg
msg['value'] = _pickle_loads(msg['value'])
File "/opt/zato/3.0/code/zato-common/src/zato/common/odb/api.py", line 67, in __getattr__
return getattr(self._elem, key)
[..] A gazillion times the same line
File "/opt/zato/3.0/code/zato-common/src/zato/common/odb/api.py", line 67, in __getattr__
return getattr(self._elem, key)
RuntimeError: maximum recursion depth exceeded
These are the contents of the variable (the output of the query) that I want to store on the cache:
2019-02-14 12:25:15,485 DEBG 'zato-server2' stdout output:
2019-02-14 12:25:15,484 - INFO - 135:DummyThread-6 - availability.search:155 - Result is: [WritableKeyedTuple('id'=6, 'floor_no'=1, 'room_no'=6, 'name'=u'Normal bedroom with one double bed', 'sgl_beds'=0, 'dbl_beds'=1, 'code'=u'brown', 'number'=u'106', 'accommodates'=2, u'nights'=9, u'total_price'=1152.0), WritableKeyedTuple('id'=2, 'floor_no'=1, 'room_no'=2, 'name'=u'Large bedroom with two single and one double beds', 'sgl_beds'=2, 'dbl_beds'=1, 'code'=u'black', 'number'=u'102', 'accommodates'=4, u'nights'=9, u'total_price'=1332.0), WritableKeyedTuple('id'=3, 'floor_no'=1, 'room_no'=3, 'name'=u'Very large bedroom with three single and one double beds', 'sgl_beds'=3, 'dbl_beds'=1, 'code'=u'white', 'number'=u'103', 'accommodates'=5, u'nights'=9, u'total_price'=1422.0)]
So it’s a list of WritableKeyedTuple objects.
This is an excerpt of the service:
class Search(Service):
class SimpleIO(object):
input_required = (Date('check_in'), Date('check_out'),
Integer('guests'))
input_optional = (List('rooms'))
output_optional = ('id', 'number', 'name', 'sbl_beds', 'dbl_beds',
'accommodates', 'code', 'nights', 'total_price')
skip_empty_keys = True
output_repeated = True
def handle(self):
conn = self.user_config.genesisng.database.connection
# [..] A lot of code to build and execute the query
if result:
self.logger.info('Result is: %s' % result)
# Store results in the cache
cache = self.cache.get_cache('builtin', 'availability')
cache_key = 'check_in:%s|check_out:%s|guests:%s|rooms:%s' % (
check_in.strftime('%Y-%m-%d'),
check_out.strftime('%Y-%m-%d'),
guests, str(rooms))
cache_data = cache.set(cache_key, result, details=True)
if cache_data:
self.response.headers['Cache-Control'] = cache_control
self.response.headers['Last-Modified'] = cache_data.\
last_write_http
self.response.headers['ETag'] = cache_data.hash
else:
self.response.headers['Cache-Control'] = 'no-cache'
# Return the result
self.response.payload[:] = result
self.response.status_code = OK
else:
self.response.status_code = NO_CONTENT
self.response.headers['Cache-Control'] = 'no-cache'
The service is working fine, returning the result and the OK status code, which leads me to believe that one way to go would be to build a list of dicts the same way the code handling the payload attribute does.
But I wanted to see if I could get some feedback before having the application doing the same job twice.
Thanks.