This would be slow and confusing. What if there is a table in the join called
first_name? What if both tables in a join have a column first_name?
On Jan 8, 2014, at 9:12 AM, Anthony wrote:
> This is an interesting idea. Instead of bothering with the "compact"
> attribute, we could make it so any Row object automatically works like a
> "compact" Row whenever it includes only one top-level key. So, if you have:
>
> <Row {'person': {'first_name': 'Bob', 'last_name': 'Smith'}}>
>
> you could do either row.person.first_name or row.first_name, regardless of
> the value of the "compact" attribute. The problem, though, is what happens if
> there is a field name that is the same as the table name. In that case, we
> would have to make the default to return either the full sub-record
> associated with the table, or just the field within the table, but neither
> approach would be fully backward compatible.
>
> I suppose we could keep using the "compact" attribute, and simply pass it to
> the Row object, so the Row object itself knows whether it is compact or not.
> This would also be necessary for the Row.as_dict and related methods to
> remain backward compatible. But then the Row object needs to be able to hold
> a private attribute (e.g., __compact).
>
> Thoughts on this?
>
> Anthony
>
> On Wednesday, January 8, 2014 9:41:19 AM UTC-5, Anthony wrote:
> Let's discuss on the developers list.
>
> 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: [email protected]
> unsubscribe: [email protected]
> 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 [email protected].
> 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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.