[Cubicweb] Proposal: new method ResultSet.one()

Rémi Cardona remi.cardona at logilab.fr
Fri Dec 6 11:06:32 CET 2013

Le 04/12/2013 16:50, Denis Laxalde a écrit :
> Christophe de Vienne a écrit :
>> I propose to add a new method to ResultSet, named one(), that would
>> return exactly one entity from the resultset.
>> If more than one row and one column, or no row at all is found, an
>> exception would be raised.
> Request's find_one_entity method does something like that, even though
> you don't write RQL.
> http://docs.cubicweb.org/devweb/request.html#cubicweb.req.RequestSessionBase.find_one_entity

Speaking of find_one_entity() and find_entities(), they currently lack 
support for reverse relations. I started adding support for it a couple 
of weeks ago inside find_entities() but didn't follow through with a 
complete patch (that, and I ended up not needing it).

Here's what I started, maybe someone will find it interesting and pick 
it up.


Rémi Cardona - LOGILAB, Paris (France).
Formations - http://www.logilab.fr/formations
Développements - http://www.logilab.fr/services
Gestion de connaissances - http://www.cubicweb.org/
-------------- next part --------------
diff --git a/req.py b/req.py
--- a/req.py
+++ b/req.py
@@ -157,11 +157,21 @@ class RequestSessionBase(object):
         >>> users = find_entities('CWGroup', name=u'users')
         >>> groups = find_entities('CWGroup')
         parts = ['Any X WHERE X is %s' % etype]
-        parts.extend('X %(attr)s %%(%(attr)s)s' % {'attr': attr} for attr in kwargs)
+        parts.extend('X %(attr)s %%(%(attr)s)s' % {'attr': attr}
+                     for attr in kwargs if not attr.startswith('reverse_'))
+        for idx, (attr, attr_val) in enumerate(kwargs.iteritems()):
+            if not attr.startswith('reverse_'):
+                continue
+            if isinstance(attr_val, int):
+                attr_val = (attr_val,)
+            d = {'attr': attr[len('reverse_'):],
+                 'idx': idx,
+                 'attr_val': ', '.join(str(x) for x in attr_val)}
+            parts.append('Y%(idx)s %(attr)s X, Y%(idx)s eid IN %(attr_val)s' % d)
         return self.execute(', '.join(parts), kwargs).entities()
     def find_one_entity(self, etype, **kwargs):
         """find one entity of the given type and attribute values.
         raise :exc:`FindEntityError` if can not return one and only one entity.

More information about the Cubicweb mailing list