cubicweb/dataimport/importer.py
changeset 11139 df928a3a94e3
parent 11128 9b4de34ad394
child 11279 e4f11ef1face
--- a/cubicweb/dataimport/importer.py	Wed Feb 03 11:12:09 2016 +0100
+++ b/cubicweb/dataimport/importer.py	Wed Feb 03 11:13:51 2016 +0100
@@ -1,4 +1,4 @@
-# copyright 2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2015-2016 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
 # contact http://www.logilab.fr -- mailto:contact@logilab.fr
 #
 # This program is free software: you can redistribute it and/or modify it under
@@ -74,6 +74,37 @@
     return use_extid_as_cwuri_filter
 
 
+def drop_extra_values(extentities, schema, import_log):
+    """Return a generator of :class:`ExtEntity` objects that will ensure their attributes and
+    inlined relations have a single value. When it's not the case, a warning will be recorded in
+    the import log and one value among other will be kept (randomly).
+
+    `schema` is the instance's schema, `import_log` is an instance of a class implementing the
+    :class:`SimpleImportLog` interface.
+
+    Example usage:
+
+    .. code-block:: python
+
+        importer = ExtEntitiesImporter(schema, store, import_log)
+        importer.import_entities(drop_extra_values(extentities, schema, import_log))
+
+    """
+    _get_rschema = schema.rschema
+    for extentity in extentities:
+        entity_dict = extentity.values
+        for key, rtype, role in extentity.iter_rdefs():
+            rschema = _get_rschema(rtype)
+            if (rschema.final or (rschema.inlined and role == 'subject')) \
+               and len(entity_dict[key]) > 1:
+                values = ', '.join(repr(v) for v in entity_dict[key])
+                import_log.record_warning(
+                    "more than one value for attribute %r, only one will be kept: %s"
+                    % (rtype, values), path=extentity.extid)
+                entity_dict[key] = set([entity_dict[key].pop()])
+        yield extentity
+
+
 class RelationMapping(object):
     """Read-only mapping from relation type to set of related (subject, object) eids.
 
@@ -161,6 +192,8 @@
         Return a list of non inlined relations that may be inserted later, each relations defined by
         a 3-tuple (subject extid, relation type, object extid).
 
+        The instance's schema is given as argument.
+
         Take care the importer may call this method several times.
         """
         assert self._schema is None, 'prepare() has already been called for %s' % self