Let's discuss on the developers 
list<https://groups.google.com/forum/?fromgroups=#!topic/web2py-developers/k2D6MVfBEYo>
.

On Tuesday, January 7, 2014 9:52:16 PM UTC-5, Joe Barnhart wrote:
>
> Maybe the best answer is to change Row so that it always holds the full 
> set of keys (table:field) and change the __getitem__ method to look up the 
> key recursively if only one part is provided.  Here is a sample method 
> which implements this strategy of testing keys for dicts within dicts.  Our 
> case is a little simpler since we never "recurse" more than one level deep.
>
> def _finditem(obj, key):
>     if key in obj: return obj[key]
>     for k, v in obj.items():
>         if isinstance(v,dict):
>             item = _finditem(v, key)
>             if item is not None:
>                 return item
>
>
> This has the advantage of working with existing code and preserving as 
> much information as possible in the Row object.  I have a feeling this 
> could make the internals of web2py a good deal more consistent.  Less 
> testing for special cases is always good!
>
> -- Joe B.
>
> On Tuesday, January 7, 2014 3:48:39 PM UTC-8, Anthony wrote:
>>
>> Note, same problem with .sort (it modifies the Row objects in 
>> self.records), so we should probably fix that as well (will be a bit more 
>> complicated).
>>
>> Anthony
>>
>> On Tuesday, January 7, 2014 11:03:56 AM UTC-5, Anthony wrote:
>>>
>>> The Rows.find() method does the following:
>>>
>>>         for row in self:
>>>             if f(row):
>>>                 if a<=k: records.append(row)
>>>                 k += 1
>>>                 if k==b: break
>>>
>>> In a Rows object, there is self.records, which is a list of Row objects. 
>>> Each Row object has at least one top-level key with the table name, and the 
>>> record is stored in the value associated with that key:
>>>
>>> <Row {'person': {'first_name': 'Bob', 'last_name': 'Smith'}}>
>>>
>>> When .find() is called on a Rows object with compact=True, the __iter__ 
>>> method (called by the "for row in self" loop) returns a transformed version 
>>> of each Row object, removing the top-level table key:
>>>
>>> <Row {'first_name': 'Bob', 'last_name': 'Smith'}>
>>>
>>> I believe this is an unnecessary transformation, and it is what is 
>>> subsequently causing the .render() method to fail (the .render() method 
>>> expects the top-level table key to be there, whether or not compact=True). 
>>> I propose the following change to .find():
>>>
>>>         for i, row in enumerate(self):
>>>             if f(row):
>>>                 if a<=k: records.append(self.records[i])
>>>                 k += 1
>>>                 if k==b: break
>>>
>>> The above code appends self.records[i] instead of row, which preserves 
>>> the original Row objects instead of including transformed objects. Anyone 
>>> see any problems with that change?
>>>
>>> Also, is there any reason all of the Rows methods (i.e., find, exclude, 
>>> __and__, __or__) should not be preserving the "compact" attribute of the 
>>> original Rows object? Perhaps we should change them all to do so. (Note, 
>>> this is a separate issue unrelated to the above problem with .find() and 
>>> .render().)
>>>
>>> Anthony
>>>
>>> On Tuesday, January 7, 2014 10:47:28 AM UTC-5, Anthony wrote:
>>>>
>>>> .render() works fine on Rows objects with compact=True, and it also 
>>>> works fine on the results of .sort(), .exclude(), &, and | operations. The 
>>>> only problem is with the results of .find() operations when the original 
>>>> Rows object has compact=True. The problem is that the .find() method 
>>>> modifies the Row objects in self.records when compact=True, which it 
>>>> probably should not due.
>>>>
>>>> Aside from this issue, perhaps the various Rows methods should preserve 
>>>> the "compact" attribute -- not sure why they don't.
>>>>
>>>> Forwarding to the developers list for discussion.
>>>>
>>>> Anthony
>>>>
>>>> On Tuesday, January 7, 2014 3:10:00 AM UTC-5, Joe Barnhart wrote:
>>>>>
>>>>> I've been experimenting with the render method of the Rows class, and 
>>>>> I am very impressed.  But one drawback I found is that the Rows object 
>>>>> must 
>>>>> have its value set to "compact=False" to work properly with render().  It 
>>>>> isn't a problem if the Rows object is used directly without any 
>>>>> operators, 
>>>>> but I discovered that many, if not most, Rows methods do not preserve the 
>>>>> "compact" setting.
>>>>>
>>>>> For example. if you "sort" the Rows, it leaves compact=True.  Ditto, 
>>>>> if you use "extract" or "find" on the Rows object.  The "&" and "|" 
>>>>> operators also set the compact variable to "True".  The upshot is that 
>>>>> you 
>>>>> can't use any of these operators on the Rows object and then use "render" 
>>>>> on the resulting object.
>>>>>
>>>>> It is a simple change to add the preservation of the "compact" flag 
>>>>> during any of these steps, but I'm unsure if this will break existing 
>>>>> code. 
>>>>>  Other than coming up with a completely parallel set of methods, which 
>>>>> leave compact set the way it came in, I can't think of another approach 
>>>>> will be provably backwards-compatible.
>>>>>
>>>>> Here is an example:
>>>>>
>>>>>
>>>>>     def __and__(self,other):
>>>>>         if self.colnames!=other.colnames:
>>>>>             raise Exception('Cannot & incompatible Rows objects')
>>>>>         records = self.records+other.records
>>>>>         return Rows(self.db,records,self.colnames)
>>>>>
>>>>>
>>>>> Becomes:
>>>>>
>>>>>
>>>>>     def __and__(self,other):
>>>>>         if self.colnames!=other.colnames:
>>>>>             raise Exception('Cannot & incompatible Rows objects')
>>>>>         records = self.records+other.records
>>>>>         return Rows(self.db,records,self.colnames,compact=(self.compact 
>>>>> or other.compact))
>>>>>
>>>>>
>>>>> In the case above, the flag compact will be set True if either of the 
>>>>> participating Rows object is also "compact".  My logic is, if you've lost 
>>>>> the "table" values on either Rows object, you may as well lose them on 
>>>>> the 
>>>>> combined set.
>>>>>
>>>>> What do you think?
>>>>>
>>>>> -- Joe B.
>>>>>
>>>>>
>>>>>

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to