list_value cannot contain a Value containing another list_value

Viewed 217

I have a 2d numeric matrix which I want to store to the cloud-datastore,

from google.cloud import datastore
client = datastore.Client(project='my-random-project')

complete_key = client.key("Task", "2185e0c5")
task = datastore.Entity(key=complete_key, exclude_from_indexes=['data'])

task.update({'data': {'input': [[1,2,3],[4,5,6],[7,8,9]], 'output': [[2,3,4],[5,6,7],[8,9,10]]}})

client.put(task)

so when I run the code above I get the following error

InvalidArgument: 400 list_value cannot contain a Value containing another list_value.

How can I put this kind of data to cloud-datastore ?

1 Answers

Quick and dirty solution: dump to json and store as a string:

import json
data_raw = {
    'input': [[1,2,3],[4,5,6],[7,8,9]],
    'output': [[2,3,4],[5,6,7],[8,9,10]]
}
task.update({'data': json.dumps(data_raw)})

You'll need to configure data to accept either stringValue (will not allow utilization of values in db side filtering/querying).

A better solution would be to store each value as an index in an object:

data_raw = {
    'input': {
        1: [1,2,3],
        2: [4,5,6],
        3: [7,8,9]
    },
    'output': {
        1: [2,3,4],
        2: [5,6,7],
        3: [8,9,10]
   }
}

I'm not 100% sure how to map the entity type here, but you do get a compatible though highly nested object. If ordering matters here but you cannot anticipate ordering ahead of time (eq to "on insert, set index"), consider using some hash algorithm to store an ordered index. This is probably a specialized use case which will take a ton of time to develop.

Related