Returning a linked table column as a dictionary

I am using the following function to get all the people from the people table.


@anvil.server.callable
def get_people():
people = app_tables.people.search()
for rows in people:
    people = [dict(rows)]
return people

one of the columns is Stuff, its a multi row link to the Stuff table, listing all the stuff each person owns.

when i print people the output list all the columns and their value for each row. For stuff the value is [<LiveObject: anvil.tables.Row>]. How can I unpack this column into a dictionary?

Would this work?

my_list=[dict(r) for r in app_tables.people.search()]
[r.update({'stuff': dict(r['stuff'])}) for r in my_list]

Completely untested, but I think in general you just have to do another layer of casting as you did initially.

Allan

i am getting
TypeError: unhashable type: ‘list’

The above should work with a single linked row (at least it did in my testing).

For multi-linked rows, see this simple clone. It prints out the fully casted list (including nested dicts). See if you can extrapolate to fit your needs.

As I mentioned above, the basic idea is to use another layer of looping to iterate through the inner list of rows, cast them to dicts, and update the outer dictionary. No magic unfortunately, just iteration.

https://anvil.works/build#clone:TL5PNLXNTG34VU7R=WDDNE35PGWTBECUPPB3FPHLW

1 Like

this is what i have

@anvil.server.callable
def get_people():
  print("start get people on server at:")
  print(datetime.now())
  people=[dict(r) for r in app_tables.people.search()]

  for d in people:
    stuff=[dict(row) for row in r['Stuff']]
    d.update({'Stuff' : stuff})
  
  print(people)
  print("finish get people on server at:")
  print(datetime.now())
  
  return people

and this is the error being returned:
NameError: name ‘r’ is not defined
Can it be BC i am running python 3.7?

here is the app:
https://anvil.works/build#clone:PXFU6X3M3XSZ7WHT=MY4VNWBBZA6GNB5THVMAPOYC

The error states that Python doesn’t know the variable r.

This should be possible for you to track down by examining your code (you may want to insert print statements here and there to examine the variables in your loop.

not sure if it a bug in anvil or a change in the python language but the sample you sent me only runs in python 2.7 when i switch to 3.7 i get the same error as when running my code which is in 3.7 runtime

The r should be a d. My clone is updated and should work under all available Pythons.

Explaination can be found here

I have added a simple object column to the transactions table in the clone of binding_idea app you shared with. how can I unpack that column as well?
here is the app
https://anvil.works/build#clone:HJ6XNUWL2HFP2D3W=6CNJ3LOD5ZBPNHRPJNWRCOLH
Thanks for the help, you have been very instructive.

What have you tried?

It is always best to ask questions by showing effort on your part. The quality of the answers is usually proportionate to the quality of the question.

1 Like

  for d in my_list:
    my_inner_dicts=[dict(row) for row in d['cust_transaction']]
    for e in my_inner_dicts:
      details = [dict(row) for row in e['details']]
      e.update({'details': details})
      
    d.update({'cust_transaction': my_inner_dicts})

getting this error:
ValueError: dictionary update sequence element #0 has length 1; 2 is required

I would suggest that you debug by printing out the values of d, d['cust_transactions'], e, and e['details] inside your loops. Something is likely amiss with one of those variables.

Also, note that simple objects don’t need to be casted to dicts as they are already treated as python dictionaries when you access them. I thought I’d point that out in case that is what you were looking to accomplish.

Lastly, it is good practice to indicate the line at which you receive the error so that it is easier for others to diagnose.

1 Like