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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.