Rows.render() needs a `rows_render`

192 views
Skip to first unread message

Chris Maps

unread,
May 8, 2021, 7:41:25 PM5/8/21
to py4web
I was learning the correct method to get the rows of a tables where I get the values of  referenced fields, not the id.  I found the render() method might be what I need.

However, when I try it I get a 'Rows.render() needs a `rows_render`' error when I call render() on selected rows.

Ultimately I want to return rows that include all the values of any referenced tables, but I cant get this to work even on the simplest example like below.  I wonder if I am not understanding the concepts.  

In a model, I have:
db.define_table('person',   Field('name'),   format='%(name)s,)
db.person.name.represent = lambda name, row: name.capitalize()

in the controller I have:
@action('index')
@action.uses(db, auth, 'index.html')
def index(path=None):
     myquery = db.person.id != None
    rows = db(myquery).select()
    repr_row = rows.render(0)
    return dict(rows=repr_row) 

If anyone has an example of how to retrieve the values of a table where all referenced field values are included in each row that I could study, maybe that would help me understand the steps.
Thanks for any advice

Chris Maps

unread,
May 9, 2021, 5:39:27 AM5/9/21
to py4web
Almost answering my own question,  using requires and filter_out like this:
db.define_table('job', Field('name'), format='%(name)s' )

db.define_table('person',
     Field('name'),
     Field('job', 'list:reference job',
            requires=IS_NULL_OR( IS_IN_DB(db, 'job.id', '%(name)s', zero='Choose one', multiple=True)),
            filter_out=lambda x:x.name if x else '' ) ,
    format='%(name)s' )

generates a 'FOREIGN KEY constraint failed' error.

From the documentation: We strongly suggest using the jQuery multiselect plugin to render multiple fields - is this why I am getting this error? If so, does someone have an example I could study?

Thanks for any thoughts

Jim Steil

unread,
May 9, 2021, 9:32:30 AM5/9/21
to py4web
Is your issue mostly with trying to build a multi-select control?  Or are you still having issues getting the referenced fields?

Regarding referenced fields.  I typically reference the value through the id field.  (I'm not positive this is what you're asking for....)

db.define_table('person',
    Field('name'))

db.define_table('dog',
     Field('owner', 'reference person', requires=IS_IN_DB(db, 'person.id', '%(name)s', zero='choose')),
     Field('name'))

for p in db(db.dog.name == 'George').select():
     print(p.name, p.owner.name)


As for the multi-select/list:reference - I've never used that before. I'm not sure how how that all works or how it is represented in the underlying database.  Hopefully someone else can help out with that.

-Jim

Kevin Koster

unread,
May 12, 2021, 10:45:21 AM5/12/21
to py4web
I'm having this exact same error message for some reason.  
>> Rows.render() needs a `rows_render` representer in DAL instance

@unauthenticated("index", "index.html")
def index():

rows = db(db.foo.id > 0).select()
for row in rows.render():
    print(row)

return locals()

I have not defined any representers in the model. However, this error persists even if I define representers for the model fields.
This is the model:

db.define_table('foo',
    Field('bar'),
    Field('foo_bar')
)

Val K

unread,
May 12, 2021, 4:18:18 PM5/12/21
to py4web
It is because web2py does this
DAL.representers = {
    'rows_render': sqlhtml.represent,  #  sqlhtml.represent  https://github.com/web2py/web2py/blob/c2ed5016e161430ecb020ddc96b16a6e5dde0e2e/gluon/sqlhtml.py#L57-L83
    'rows_xml': sqlhtml.SQLTABLE
}


as hotfix (while Massimo decides if this is a bug or feature ;) you can do the following:
- create some module in your app dir, (e.g. my_utils.py) and place in it these 2 functions: https://github.com/web2py/web2py/blob/c2ed5016e161430ecb020ddc96b16a6e5dde0e2e/gluon/sqlhtml.py#L57-L83
- in common.py or models.py:

import my_utils

DAL.representers = {
    'rows_render':  my_utils.represent, 
}


среда, 12 мая 2021 г. в 17:45:21 UTC+3, Kevin Koster:

Massimo

unread,
May 13, 2021, 1:36:19 AM5/13/21
to py4web
Mind that:

DAL.representers = {...}

is not thread safe in py4web so you have to do:

db.representers = { .. }

For the exact format of the function I suggest you look into web2py's sqlhtml.represent which you referenced.

Kevin Koster

unread,
May 14, 2021, 3:52:09 AM5/14/21
to py4web
Ok so, i created a module with these functions in it:

Now whenever i do this:

from . import my_util

db.representers = {
    'rows_render': my_util.represent
}

it gives me the following error:
TypeError: cannot pickle 'module' object



Op donderdag 13 mei 2021 om 07:36:19 UTC+2 schreef Massimo:

Val K

unread,
May 14, 2021, 5:30:07 PM5/14/21
to py4web
It seems that there is a bug here: 
https://github.com/web2py/pydal/blob/232e841765ee97ac6f7af45be794d46432085c4d/pydal/objects.py#L256-L257

I suppose it should be:
def pickle_row(s):
    return Row, ({k: s[k] for k in s if k not in ('update_record', 'delete_record')},)


пятница, 14 мая 2021 г. в 10:52:09 UTC+3, koster...@gmail.com:

Kevin Keller

unread,
May 16, 2021, 5:51:04 AM5/16/21
to Val K, py4web
Val, your bugfix works. 

Just tested it.


Thank you!



--
You received this message because you are subscribed to the Google Groups "py4web" group.
To unsubscribe from this group and stop receiving emails from it, send an email to py4web+un...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/py4web/abe0f0f5-6bd6-4f5e-adf2-419a3f6c2cb4n%40googlegroups.com.

Kevin Koster

unread,
May 18, 2021, 7:24:16 AM5/18/21
to py4web
It does not seem to work for me. I have edited line 255 of objects.py. I have changed it to the solution you gave. 
However, I still get the same error message: TypeError: cannot pickle 'module' object. 

I just assumed that I had to change this line inside the site-packages. Am I doing something wrong?

Op zondag 16 mei 2021 om 11:51:04 UTC+2 schreef kell...@gmail.com:

Kevin Keller

unread,
May 18, 2021, 7:31:31 AM5/18/21
to Kevin Koster, py4web
It should work. 

Maybe you are using a python version different to the one where you patched the line in site_packages? 
Or there is a pyc file cached somewhere in site_packages with the old code?

I tested it by changing the code in site packages as well and it worked. 

Afterwards I applied the patch to my personal pydal version here :

So you can also create a new virtual env to test it with that pydal version as well if you like. 



git clone it and then install via pip install -e piedal (where piedal is the cloned folder) 


Kevin Koster

unread,
May 18, 2021, 8:54:10 AM5/18/21
to py4web
Nope, still doesn't work. I've tried installing your version of pydal as well as an editable version of the normal pydal.
I get about the same error message:  TypeError: can't pickle module objects.

And yes, in both cases I was using a completely clean virtual environment.
Op dinsdag 18 mei 2021 om 13:31:31 UTC+2 schreef kell...@gmail.com:

Kevin Keller

unread,
May 18, 2021, 9:28:47 AM5/18/21
to Kevin Koster, py4web
Ok can you click on download app and share the zip file of your app. 

I will try to debug your code properly. 

If you like you can also share it via discord.

We have a py4web discord server.





Reply all
Reply to author
Forward
0 new messages