Thank you. :-) On Wednesday, 8 January 2014 12:28:18 UTC-6, Anthony wrote: > > OK, good point. In that case, I'll just send a patch for .find and .sort > so they return the original self.records items so .render will work > properly. > > Anthony > > On Wednesday, January 8, 2014 11:47:24 AM UTC-5, Massimo Di Pierro wrote: >> >> The problem is speed. I believe the getitem should be as fast as >> possible. This was changed before so that the trasformation of the rows >> occurred only once and not every time a row column is accessed. >> >> On Jan 8, 2014, at 8:41 AM, Anthony wrote: >> >> 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. >>>>>>> >>>>>>> >>>>>>> >> -- >> -- mail from:GoogleGroups "web2py-developers" mailing list >> make speech: web2py-d...@googlegroups.com >> unsubscribe: web2py-develop...@googlegroups.com >> details : http://groups.google.com/group/web2py-developers >> the project: http://code.google.com/p/web2py/ >> official : http://www.web2py.com/ >> --- >> You received this message because you are subscribed to the Google Groups >> "web2py-developers" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to web2py-develop...@googlegroups.com. >> For more options, visit https://groups.google.com/groups/opt_out. >> >> >>
-- 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.