I'm having a problem on how I will get the data/value from the field which is an array. Please see image:
In the image, I want to get the data/value of parking_code which is from the array field (parkings).
I tried this one:
parking2 = db.collection(u'parking').document().get({u'parkings.parking_code'})
but it returns me like this: <google.cloud.firestore_v1.document.DocumentSnapshot object at 0x0000014925256550>
I also tried this kind of code:
parking2 = db.collection(u'parking').document().get({u'parkings.parking_code'}).to_dict()
but it returns a None value. Anyone who has solution on this or at least just an idea, please I need your help.
According to the official documentation:
A DocumentSnapshot contains data read from a document in your Cloud
Firestore database. The data can be extracted with the getData() or
get(String) methods.
If the DocumentSnapshot points to a non-existing document, getData()
and its corresponding methods will return null. You can always
explicitly check for a document's existence by calling exists().
doc_ref = db.collection(u'parking').document(u'D7k...')
doc = doc_ref.get()
print(doc.to_dict())
https://cloud.google.com/firestore/docs/query-data/get-data#custom_objects
I have this JSON object and i like to update a value within the object. I found a way how i should do this on stackoverflow (Json handling in ROBOT) and its failing and i don't understand why.
This is de object:
{"elementKey":"P690-C0-C3-B1","fields":[{"key":"P690-C1-C2-C1-C1-C1-F0","values":[]},{"key":"P690-C0-C2-F8","values":["1200"]},{"key":"P690-C0-C2-F9","values":["22000"]},{"key":"P690-C0-C2-F11","values":["I"]},{"key":"P690-C0-C2-F10","values":["2200"]},{"key":"P690-C0-C2-C0-C0-F0","values":["98-zsg-2"]},{"key":"P690-C1-C0-C0-F1","values":["Personenauto"]},{"key":"P690-C1-C0-C0-F2","values":["Personenauto KVP"]},{"key":"P690-C0-C2-F6","values":["B"]},{"key":"P690-C0-C2-F7","values":["75"]},{"key":"P690-C0-C2-F4","values":["2"]},{"key":"P690-C0-C2-F5","values":["5"]},{"key":"P690-C0-C2-F2","values":["model"]},{"key":"P690-C0-C2-F3","values":["2017"]},{"key":"P690-C1-C2-C2-C2-C1-F0","values":[]},{"key":"P690-C0-C2-F1","values":["merk"]}]}
In Robot frame I made this test, inspired on the given link.
${json_string}= Set Variable "see text above"
${json}= Evaluate json.loads('''${json_string}''') json
Set To Dictionary ${json["fields"]} ${new_value}
${json_string}= evaluate json.dumps(${json}) json
With ${new_value} i tried value=shizzleliz, value[0]=shizzleliz, value[1]=shizzleliz, P690-C1-C2-C1-C1-C1-F0=shizzleliz
All give the error: AttributeError: 'list' object has no attribute 'update'
When i change ${json["fields"]} to ${json} then the give value is set to the library but not in de fields section/collection.
Does anyone have a clue of what i'm doing wrong? And if you have a suggestion how i can update the value, i'd like that very much :)
target is to change: {"key":"P690-C1-C2-C1-C1-C1-F0","values":[]}
to: {"key":"P690-C1-C2-C1-C1-C1-F0","values":["shizzleliz"]}
For the first part in your question - the error AttributeError: 'list' object has no attribute 'update', you've already seen the comment - you're calling Set To Dictionary on a list object, which cannot pass.
For the second part, in order to set that value when the key is equal to something, you have to iterate over all the list members, and set it based on a condition over the key:
${json_string}= Set Variable see text above
${json1}= Evaluate json.loads('''${json_string}''') json
${target value}= Create List shizzleiz
:FOR ${element} IN #{json1["fields"]}
\ Run Keyword If "${element['key']}" == "P690-C1-C2-C1-C1-C1-F0"
... Set To Dictionary ${element} values=${target value}
${json_string}= evaluate json.dumps(${json1}) json
It looks a little cumbersome in RF (compared to python); one remark - it's never a good idea to name a local variable the same as a module - thus I've renamed it to ${json1}
I found an easier solution using Catenate where I needed to randomize two values in the json body.
${shizzleiz}= shizzleiz # or whatever you want to appear there
${json_string}= Catenate {"elementKey":"P690-C0-C3-B1","fields":[{"key":"P690-C1-C2-C1-C1-C1-F0","values":[]},{"key":"P690-C0-C2-F8","values":["1200"]},{"key":"P690-C0-C2-F9","values":["22000"]},{"key":"P690-C0-C2-F11","values":["I"]},{"key":"P690-C0-C2-F10","values":["2200"]},{"key":"P690-C0-C2-C0-C0-F0","values":["98-zsg-2"]},{"key":"P690-C1-C0-C0-F1","values":["Personenauto"]},{"key":"P690-C1-C0-C0-F2","values":["Personenauto KVP"]},{"key":"P690-C0-C2-F6","values":["B"]},{"key":"P690-C0-C2-F7","values":["75"]},{"key":"P690-C0-C2-F4","values":["2"]},{"key":"P690-C0-C2-F5","values":["5"]},{"key":"P690-C0-C2-F2","values":["model"]},{"key":"P690-C0-C2-F3","values":["2017"]},{"key":"P690-C1-C2-C2-C2-C1-F0","values": ${shizzleiz} ${the-rest-of-the-long-json-as-a-string}
then continue on with:
${json}= Evaluate json.loads('''${json_string}''') json
${json_string}= evaluate json.dumps(${json}) json
(basically do the work before reacting to the json function - obviously this requires knowing the values beforehand and could also work with more variables.)
I want to get all the field names of a proto into a list. Is there a way to do this? I looked in the documentation and there doesn't seem to be anything for this.
Every proto class possess a DESCRIPTOR class variable that can be used to inspect the fields of corresponding protobuf messages.
Have a look at the documentation of the Descriptor and FieldDescriptor classes for more details.
Here is a simple example to get the FieldDescriptors of all the fields in message into a list:
res = message.DESCRIPTOR.fields
To get the names of the fields "exactly as they appear in the .proto file":
res = [field.name for field in message.DESCRIPTOR.fields]
or (from the comments):
res = message.DESCRIPTOR.fields_by_name.keys()
To get the full names of the fields "including containing scope":
res = [field.full_name for field in message.DESCRIPTOR.fields]
qfiard's answer didn't work for me. Calling message.DESCRIPTOR.fields.keys() produced AttributeError: 'list' object has no attribute 'keys'.
Not sure why it wouldn't work. Maybe it has something to do with how the message was defined/compiled.
The workaround was to do a list composition of the individual field objects and get the name property for each. This gave me a list of strings of all fields in this list.
res = [f.name for f in message.DESCRIPTOR.fields]
Note that this does not get you the field names within those fields recursively.
You can easily get a list of fields as follows
message_fields = [field for field in message.DESCRIPTOR.fields_by_name]
I bumped to Python 3.9 and some of these solutions broke, so I found a solution using the public interface of a message object, not using the DESCRIPTOR attribute.
fields = [desc.name for desc, val in message.ListFields()]
Note however, this solution will only fetch the fields which have been set.
Doc is here: https://googleapis.dev/python/protobuf/latest/google/protobuf/message.html#google.protobuf.message.Message.ListFields
I trying to create a json object and pass that object to template.render(JSONObj), but there is some error saying
ValueError: dictionary update sequence element #0 has length 1; 2 is required
What am I doing wrong?
You have to give that "JSONObj" object a key value. The template recieves a dictionary with objects and values to render inside it. So, try using this:
template.render(jsonobj=JSONObj)
Then, in your template, you can use this object this way:
{{jsonobj.some_key_inside_json_object}}
This jsonobj is a name that identifies your "JSONObj" object inside the template's arguments.
Hope it helps!
I’m trying to write a response from a Solr server to a CSV file. I’m pretty new to python and have been given code to modify. Originally the code looked like this ...
for doc in response.results:
status = json.loads(doc['status'])
The script runs and prints the correct information. But it only every prints one result (last one). I think this is because the loop constantly writes over the varible 'status' until its worked through the response.
After some reading I decided to store the information in a list. That way i could print the information to seprate lines in a list. I created an empty list and changed the code below -
for doc in response.results:
list.append = json.loads(doc['status'])
I got this response back after trying to run the code -
`AttributeError: 'list' object attribute 'append' is read-only`.
Where am I going wrong? Is a list not the best approach?
>>> list.append
<method 'append' of 'list' objects>
You're trying to modify the append method of the built-in list class!
Just do
docstats = []
for doc in response.results:
docstats.append(json.loads(doc['status']))
or equivalently:
docstats = [json.loads(doc['status']) for doc in response.results]
I'm not sure what you are trying to do.
I guess you haven't created a list variable. list is a python's builtin class for lists, so if there's no variable to mask it, you'll access that. And you tried to modify one of it's propterties, which is not allowed (it's not like ruby where you can monkey-patch anything).
Is this what you want? :
l=[]
for doc in response.results:
l.append(json.loads(doc[‘status’]))
Try
list.append(json.loads(doc['status']))