The default object returned by
Cluster.n1ql_query is a
couchbase.n1ql.N1QLRequest object, as described here:
This simply implements the iterator protocol. Each result returned by
next() from this iterator is simply a transcoded version of the data contained in a single N1QL result row. As N1QL requests return a JSON result, this would by default be a Python object, i.e. a list, value or dictionary, as
json.loads would produce when decoding JSON.
It looks like you’re turning the JSON structure back into a string and then performing string operations on the stringified data. It would seem likely that any manipulations you need to do that involve parsing the JSON representation would be better done using the parsed version, i.e. the native Python objects.
In this case, it looks like you are retrieving the value of the first entry in the returned dictionary. You can get this as follows:
row.values().iter().next(<default value>) . # <default value> will be returned if there are no entries
Or if you know this value will be associated with a specific key (which would most likely be more reliable), then you can write:
row.get("key", <default value>) # <default value> will be returned if the key is not present.
In SDK2 it is up the end-user to map values back to a given class, either using their own transcoder or by taking the already decoded values and further marshalling them to the target data type. We are working on a new transcoding protocol for SDK3 that will formalise this further.
Hope that helps,