0

I got Map datatype that I am storing in RIAK. It's Map that contains few Maps that contain counters. The expected output of serializing to json program would be:

{
"sample_map_key" : {
    "maps" : {
        "Q1" : {
            "counters" : {
                "a1" : 10,
                "a2" : 13
            }
        },
        "Q2" : {
            "counters" : {
                "a1":31,
                "a2":21,
                "a3":10
            }
        }
    }
}

But instead I am getting exception: "TypeError: unhashable type: 'Map'". Thanks for your help. Here are the sample codes:

from riak.datatypes import Map
import riak
def main():
    store_values()
    read_values()

def store_values():
    riak_client = riak.RiakClient(host="localhost", http_port="8087", protocol="pbc")
    mapBucketType = riak.BucketType(riak_client, "maps")
    maps_bucket = riak.RiakBucket(riak_client, "sample_maps_bucket", mapBucketType)
    sample_map = Map(maps_bucket, "sample_map_key")
    sample_map.maps["Q1"].counters["a1"].increment(10)
    sample_map.maps["Q1"].counters["a2"].increment(13)
    sample_map.maps["Q2"].counters["a1"].increment(31)
    sample_map.maps["Q2"].counters["a2"].increment(21)
    sample_map.maps["Q2"].counters["a3"].increment(10)
    sample_map.store()

def read_values():
    riak_client = riak.RiakClient(host="localhost", http_port="8087", protocol="pbc")
    mapBucketType = riak.BucketType(riak_client, "maps")
    maps_bucket = riak.RiakBucket(riak_client, "sample_maps_bucket", mapBucketType)
    sample_map = Map(maps_bucket, "sample_map_key")
    sample_map.reload()
    results = {"sample_map_key": to_json(sample_map)}
    print results

def to_json(map):
        obj = {}
        for m in map.maps:
            if "maps" not in obj:
                obj["maps"] = {}
            obj["maps"][m] = to_json(map.maps[m])
        for c in map.counters:
            if "counters" not in obj:
                obj["counters"] = {}
            obj["counters"][c] = map.counters[c]
        return obj

if __name__ == '__main__':
    main()

Full traceback:

Traceback (most recent call last):   File "sampleMap.py", line 48, in <module>
    main()   File "sampleMap.py", line 5, in main
    read_values()   File "sampleMap.py", line 31, in read_values
    results = {"sample_map_key": to_json(sample_map)}   File "sampleMap.py", line 40, in to_json
    obj["maps"][m] = to_json(map.maps[m])   File "/usr/local/lib/python2.7/dist-packages/riak/datatypes/map.py", line 26, in __getitem__
    return self.map[(key, self.datatype)]   File "/usr/local/lib/python2.7/dist-packages/riak/datatypes/map.py", line 171, in __getitem__
    if key in self._value: TypeError: unhashable type: 'Map'
Rekr
  • 11
  • 2

1 Answers1

1

Ok. I got it working. It seems that there is an inconsistency between the RIAK library and description. Iterating over map.maps is not yielding keys but values. But, if you iterate over map itself you will get the key/type touple. Here are the working codes:

from riak.datatypes import Map
import riak
def main():
    store_values()
    read_values()

def store_values():
    riak_client = riak.RiakClient(host="localhost", http_port="8087", protocol="pbc")
    mapBucketType = riak.BucketType(riak_client, "maps")
    maps_bucket = riak.RiakBucket(riak_client, "sample_maps_bucket", mapBucketType)
    sample_map = Map(maps_bucket, "sample_map_key")
    sample_map.maps["Q1"].counters["a1"].increment(10)
    sample_map.maps["Q1"].counters["a2"].increment(13)
    sample_map.maps["Q2"].counters["a1"].increment(31)
    sample_map.maps["Q2"].counters["a2"].increment(21)
    sample_map.maps["Q2"].counters["a3"].increment(10)
    sample_map.store()

def read_values():
    riak_client = riak.RiakClient(host="localhost", http_port="8087", protocol="pbc")
    mapBucketType = riak.BucketType(riak_client, "maps")
    maps_bucket = riak.RiakBucket(riak_client, "sample_maps_bucket", mapBucketType)
    sample_map = Map(maps_bucket, "sample_map_key")
    sample_map.reload()
    results = {"sample_map_key": to_json(sample_map)}
    print results

def to_json(map):
        obj = {}
        for m, type in map:
            if (type == "map"):
                if "maps" not in obj:
                    obj["maps"] = {}
                obj["maps"][m] = to_json(map.maps[m])

            if (type == "counter"):
                if "counters" not in obj:
                    obj["counters"] = {}
                obj["counters"][m] = map.counters[m].value
        return obj

if __name__ == '__main__':
    main()
Rekr
  • 11
  • 2