[datafeed parser] only update an entity attributes when needed. Closes #1989142 stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Tue, 11 Oct 2011 13:50:32 +0200
branchstable
changeset 7932 2ad26cc3b5c6
parent 7930 664d52cb936d
child 7933 b25dda2214a2
[datafeed parser] only update an entity attributes when needed. Closes #1989142 This may avoid error with some entities which have immutable attributes and don't check something actually changed. Also, avoid modifying the cached item representation, this may cause pb when an item is seen several times during an import.
sobjects/parsers.py
--- a/sobjects/parsers.py	Tue Oct 11 10:59:35 2011 +0200
+++ b/sobjects/parsers.py	Tue Oct 11 13:50:32 2011 +0200
@@ -72,7 +72,7 @@
     typeddict = {}
     for rschema in eschema.subject_relations():
         if rschema.final and rschema in stringdict:
-            if rschema == 'eid':
+            if rschema in ('eid', 'cwuri', 'cwtype', 'cwsource'):
                 continue
             attrtype = eschema.destination(rschema)
             value = stringdict[rschema]
@@ -200,8 +200,8 @@
         * `rels` is for relations and structured as
            {role: {relation: [(related item, related rels)...]}
         """
-        entity = self.extid2entity(str(item.pop('cwuri')),  item.pop('cwtype'),
-                                   cwsource=item.pop('cwsource'), item=item)
+        entity = self.extid2entity(str(item['cwuri']),  item['cwtype'],
+                                   cwsource=item['cwsource'], item=item)
         if entity is None:
             return None
         if entity.eid in self._processed_entities:
@@ -209,10 +209,16 @@
         self._processed_entities.add(entity.eid)
         if not (self.created_during_pull(entity) or self.updated_during_pull(entity)):
             self.notify_updated(entity)
-            item.pop('eid')
-            # XXX check modification date
             attrs = extract_typed_attrs(entity.e_schema, item)
-            entity.set_attributes(**attrs)
+            # check modification date and compare attribute values to only
+            # update what's actually needed
+            entity.complete(tuple(attrs))
+            mdate = attrs.get('modification_date')
+            if not mdate or mdate > entity.modification_date:
+                attrs = dict( (k, v) for k, v in attrs.iteritems()
+                              if v != getattr(entity, k))
+                if attrs:
+                    entity.set_attributes(**attrs)
         self.process_relations(entity, rels)
         return entity