new experimental feature in trunk - rows.join(...)

260 views
Skip to the first unread message

Massimo Di Pierro

unread,
5 Jul 2016, 14:20:0605/07/2016
to web2py-users

db = DAL()

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

db.define_table('thing',Field('name'),Field('owner','reference person'))


for name in ('Max','Tim','Jim'):

    i = db.person.insert(name=name)

    for thing in ('Chair','Table','Bike'):

        db.thing.insert(owner=i, name=name+"'s "+thing)


rows = db(db.thing).select().join(db.person.id)

print(rows.as_json())


"""                                                                                                                                                                                        

[{"owner": {"id": 1, "name": "Max"}, "id": 1, "name": "Max's Chair"},                                                                                                                      

 {"owner": {"id": 1, "name": "Max"}, "id": 2, "name": "Max's Table"},                                                                                                                      

 {"owner": {"id": 1, "name": "Max"}, "id": 3, "name": "Max's Bike"},                                                                                                                       

 {"owner": {"id": 2, "name": "Tim"}, "id": 4, "name": "Tim's Chair"},                                                                                                                      

 {"owner": {"id": 2, "name": "Tim"}, "id": 5, "name": "Tim's Table"},                                                                                                                      

 {"owner": {"id": 2, "name": "Tim"}, "id": 6, "name": "Tim's Bike"},                                                                                                                       

 {"owner": {"id": 3, "name": "Jim"}, "id": 7, "name": "Jim's Chair"},                                                                                                                      

 {"owner": {"id": 3, "name": "Jim"}, "id": 8, "name": "Jim's Table"},                                                                                                                      

 {"owner": {"id": 3, "name": "Jim"}, "id": 9, "name": "Jim's Bike"}]                                                                                                                       

"""



rows = db(db.person).select().join(db.thing.owner, name="owns", fields=[db.thing.id, db.thing.name])

print(rows.as_json())


"""                                                                                                                                                                                        

[{"id": 1, "name": "Max", "owns": [                                                                                                                                                        

    {"id": 1, "name": "Max's Chair"},                                                                                                                                                      

    {"id": 2, "name": "Max's Table"},                                                                                                                                                      

    {"id": 3, "name": "Max's Bike"}]},                                                                                                                                                     

 {"id": 2, "name": "Tim", "owns": [                                                                                                                                                        

    {"id": 4, "name": "Tim's Chair"},                                                                                                                                                      

    {"id": 5, "name": "Tim's Table"},                                                                                                                                                      

    {"id": 6, "name": "Tim's Bike"}]},                                                                                                                                                     

 {"id": 3, "name": "Jim", "owns": [                                                                                                                                                        

    {"id": 7, "name": "Jim's Chair"},                                                                                                                                                      

    {"id": 8, "name": "Jim's Table"},                                                                                                                                                      

    {"id": 9, "name": "Jim's Bike"}]}                                                                                                                                                      

]                                                                                                                                                                                          

"""


this is designed to be efficient and work on GAE too as long as rows is not too long.

Carlos Cesar Caballero Díaz

unread,
5 Jul 2016, 15:14:0705/07/2016
to web...@googlegroups.com
Massimo, that's great!!

Could work with multiple levels of relations? Giving something like:

{"owner": {"id": 1, "name": "Max", "owner_of_owner":{"id": 1, "data": "the data"}}, "id": 1, "name": "Max's Chair"}

Or can be used to build that (https://groups.google.com/d/topic/web2py/89byxw7BYwc/discussion) functionality? (Maybe I can build it now using your code as base, with other name as Anthony suggests)

Greetings.

El 05/07/16 a las 14:20, Massimo Di Pierro escribió:
--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Massimo Di Pierro

unread,
5 Jul 2016, 16:36:4605/07/2016
to web2py-users
Turns out I had to make some change but I got this to work:

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

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

db.define_table('purchase',Field('person','reference person'),Field('product','reference product'))


rows = db(db.person).select().join(db.purchase.person, # the thing you want to join by

                                   constraint=(db.purchase.product==db.product.id), # the many2many

                                   fields=[db.product.id, db.product.name], # the fields you want

                                   orderby=db.product.name, # the order

                                   name='purchases', # how you want to call it

                                   )

print(rows.as_json())

"""                                                                                                                

[{"name": "Max", "purchases": [{"id": 1, "name": "Book"}, {"id": 3, "name": "Jewel"}], "id": 1}, {"name": "Tim", "purchases": [{"id": 2, "name": "Bike"}], "id": 2}, {"name": "Jim", "purchases": [{"id": 1, "name": "Book"}, {"id": 3, "name": "Jewel"}], "id": 3}, {"name": "Max", "purchases": [], "id": 4}, {"name": "Tim", "purchases": [], "id": 5}, {"name": "Jim", "purchases": [], "id": 6}]                                                                      

To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscribe@googlegroups.com.

Marlysson Silva

unread,
6 Jul 2016, 07:24:5306/07/2016
to web2py-users
Great funcionality!!

Ron Chatterjee

unread,
6 Jul 2016, 11:12:2706/07/2016
to web2py-users
I am not too familiar with python way of looping since I come from traditional coding background. How would this for loop be implemented? in terms of.

persons = {'Max','Tim','Jim'};
item = {'Chair','Table','Bike''};

#nested for loop.

for i in range of len(persons):
        ii = db.person.insert(name=persons[i]);
         for j in range of len(item):
                db.thing.insert(owner=ii, name=persons[i]+"'s "+item[j]);

#no end needed for the loop to finish.

rows = db(db.thing).select().join(db.person.id)

print(rows.as_json())

Am I correct?

Anthony

unread,
6 Jul 2016, 12:14:0006/07/2016
to web2py-users
It's not quite clear what you are asking. It looks like you are implementing the same looping as in Massimo's original example -- what was wrong with that code? Anyway, if you want to use an index in the loop, it would be range(len(persons)).

Anthony

Ron Chatterjee

unread,
6 Jul 2016, 13:21:3306/07/2016
to web2py-users
range (0, len (item)). a define incremental value defaulted as 1. I am saying there is another way to write the same. But you are right Anthony. Its same.

Anthony

unread,
6 Jul 2016, 13:24:3606/07/2016
to web2py-users
On Wednesday, July 6, 2016 at 1:21:33 PM UTC-4, Ron Chatterjee wrote:
range (0, len (item))

That's the same as range(len(item)).

Anthony

Marlysson Silva

unread,
6 Jul 2016, 13:41:5706/07/2016
to web...@googlegroups.com
To get the index of list , too could use "for index, value in enumerate(list)" .



--
You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/_xQUWYXZG54/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+un...@googlegroups.com.

Mirek Zvolský

unread,
7 Jul 2016, 06:31:3007/07/2016
to web2py-users
Massimo, this is great !

From your second example I think, it could work for serial m:1 joins too.
Example:
invoice_item >- product >- product_group
If I want list invoice_items with product.name + with product_group.name

Realy is this now possible?





Dne úterý 5. července 2016 20:20:06 UTC+2 Massimo Di Pierro napsal(a):

Massimo Di Pierro

unread,
11 Jul 2016, 02:01:1911/07/2016
to web2py-users
yes. you can do that.

Carlos Cesar Caballero

unread,
30 Jul 2016, 00:24:1730/07/2016
to web2py-users
Hi Massimo, this new functionality is great!! How will be the syntax for the Mirek use case?
And what if we have something like invoice_item >- product >- product_group >- group_thing ?
And more and more and more?

Greetings.

Jurgis Pralgauskis

unread,
5 Mar 2017, 23:44:0905/03/2017
to web2py-users

Richard Vézina

unread,
6 Mar 2017, 10:00:1806/03/2017
to web2py-users
Hello Jurgis, maybe it could be included as a contrib?? 

Because as Giovanni mention, your proposal would make the DAL more of an ORM in case it been included. 

Richard

--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscribe@googlegroups.com.

Jurgis Pralgauskis

unread,
6 Mar 2017, 10:20:0106/03/2017
to web...@googlegroups.com
I'd like to. 
But it needs review and tests, I guess.

You received this message because you are subscribed to a topic in the Google Groups "web2py-users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/web2py/_xQUWYXZG54/unsubscribe.
To unsubscribe from this group and all its topics, send an email to web2py+unsubscribe@googlegroups.com.

Marlysson Silva

unread,
6 Mar 2017, 10:21:2606/03/2017
to web...@googlegroups.com
The tests in contrib module are made by creator of module ( the core developer of web2py don't test them ) .

Desenvolvedor Frontend com um pé no Backend , e vice-versa. 
Github: github.com/Marlysson

Richard Vézina

unread,
6 Mar 2017, 10:24:3006/03/2017
to web2py-users
I would not say it good practice but not all contrib that have been include are tested... But it definitly a good idea to test it properly and have test, so if the core change and you code break you know were it from (which commit to the core) as long as these tests are included in test suit.

Richard

Marlysson Silva

unread,
6 Mar 2017, 10:29:1606/03/2017
to web...@googlegroups.com
It ever good have the software tested.

Desenvolvedor Frontend com um pé no Backend , e vice-versa. 
Github: github.com/Marlysson

Jurgis Pralgauskis

unread,
9 Mar 2017, 23:29:5109/03/2017
to web2py-users
What is more efficient on relational DB (for ex., postgre):  join(..)  or  group_by_val(..)  

rows = db(db.person).select().join(db.thing.owner, name="owns", fields=[db.thing.iddb.thing.name])  

vs

rows = db(db.person).select( db.person.All, db.thing.id, db.thing.name,  join=[ ..on.db.thing.owner=...,) ).group_by_val( db.person.id
# 1 db request, but more duplicating info in fetched rows

ps.: maybe join(..) could be named "join_grouped" for less confusion with select's arg "join" (and better hint what it does)
Reply all
Reply to author
Forward
0 new messages