def create_or_link_slaves(how: ImportHow, session: Session, object_head_to_write, object_fields_to_write, image_to_write) -> int: """ Create, link or update slave entities, i.e. head, fields, image. Also update them... TODO: Split/fork the def :returns the number of new records """ if object_head_to_write.orig_id in how.existing_objects: # Set the objid which will be copied for storing the image, the object itself # will not be stored due to returned value. objid = how.existing_objects[object_head_to_write.orig_id] object_head_to_write.objid = objid if how.can_update_only: # noinspection DuplicatedCode for a_cls, its_pk, an_upd in zip( [ObjectHeader, ObjectFields], ['objid', 'objfid'], [object_head_to_write, object_fields_to_write]): filter_for_id = text("%s=%d" % (its_pk, objid)) # Fetch the record to update obj = session.query(a_cls).filter(filter_for_id).first() if a_cls == ObjectHeader: # Eventually refresh sun position if an_upd.nb_fields_from(USED_FIELDS_FOR_SUNPOS) > 0: # Give the bean enough data for computation for a_field in USED_FIELDS_FOR_SUNPOS.difference( an_upd.keys()): an_upd[a_field] = getattr(obj, a_field) TSVFile.do_sun_position_field(an_upd) updates = TSVFile.update_orm_object(obj, an_upd) # type: ignore if len(updates) > 0: logger.info("Updating '%s' using %s", filter_for_id, updates) session.flush() ret = 0 # nothing to write else: # 'Simply' a line with a complementary image logger.info("One more image for %s:%s ", object_head_to_write.orig_id, image_to_write) ret = 1 # just a new image else: if how.can_update_only: # No objects creation while updating logger.info("Object %s not found while updating ", object_head_to_write.orig_id) ret = 0 else: # or create it # object_head_to_write.projid = how.prj_id object_head_to_write.random_value = random.randint(1, 99999999) # Below left NULL @see self.update_counts_and_img0 # object_head_to_write.img0id = XXXXX ret = 3 # new image + new object_head + new object_fields return ret
def create_parent(session: Session, dict_to_write, prj_id: ProjectIDT, parent_class): """ Create the SQLAlchemy wrapper for Sample, Acquisition or Process. :return: The created DB wrapper. """ # noinspection PyCallingNonCallable parent = parent_class(**dict_to_write) # Link with project parent.projid = prj_id session.add(parent) session.flush() return parent
def update_parent_objects(how: ImportHow, session: Session, dicts_for_update: Mapping[str, Dict]): """ Update of Sample, Acquisition & Process. For locating the records, we tolerate the lack of orig_id like during creation. """ assert how.can_update_only upper_level_pk = how.prj_id # Loop up->down, i.e. Sample to Process parent_class: ParentTableClassT for alias, parent_class in GlobalMapping.PARENT_CLASSES.items(): # The data from TSV, to update with. Eventually just an empty dict, but still a dict. dict_for_update = dicts_for_update[alias] if parent_class != Process: # Locate using Sample & Acquisition orig_id parent_orig_id = dict_for_update.get("orig_id") if parent_orig_id is None: # No orig_id for parent object in provided dict # Default with present parent's parent technical ID parent_orig_id = '__DUMMY_ID__%d__' % upper_level_pk # Look for the parent by its (eventually amended) orig_id parents_for_obj: Dict[ str, ParentTableT] = how.existing_parents[alias] parent = parents_for_obj.get(parent_orig_id) if parent is None: # No parent found to update, thus we cannot locate children, as there # is an implicit relationship just by the fact that the 3 are on the same line break # Collect the PK for children in case we need to use a __DUMMY upper_level_pk = parent.pk() else: # Fetch the process from DB parent = session.query(Process).get(upper_level_pk) assert parent is not None # OK we have something to update # Update the DB line using sqlalchemy updates = TSVFile.update_orm_object(parent, dict_for_update) if len(updates) > 0: logger.info("Updating %s '%s' using %s", alias, parent.orig_id, updates) session.flush()