I was interested in creating a generic helper function to get the 
instrumented list associated with a "RelationshipProperty" for a Model,
you can get the relationship from 
inspect(model).mapper.relationships.items(), but the relationship is just 
the RelationshipProperty object and *not* the InstrumentedList.  I could 
not see a way to get the instrumented list from the relationship and was 
wondering if I was missing something or if we really must use 
getattr(model, property_name) to get the InstrumentedList.

I also noticed that I couldn't directly set the instrumented list values 
from the relationship; I can do add/remove/extend operations on the list 
but not e.g. `relationship = [item1, item2, item3,]`, for that I had to use 
setattr(model, relationship_name, values_array)

Any feedback on my approach or if there is a better way to do this would be 
appreciated!

def type_query(type, id):
    type_query = g.session.query(type).filter_by(id=id).one()
    return type_query

def get_relationship_from_model(parent_entity, relationship_model):
    relationship_label = None
    for label, r in inspect(parent_entity).mapper.relationships.items():
        if r.entity.class_ == relationship_model:
            relationship_label = label
            break
    relationship = getattr(parent_entity, relationship_label)
    return relationship_label, relationship


def update_list(relationship_model, entity_model, operation: str, id_list: 
Optional[List[UUID]] = None):
    """
    id list = ids to add or remove from relationship
    relationship_type = the `type` of the relationship on entity model, e.g...
    entity_model = the model whose relationships are being updated
    operation = add or remove
    :param id_list:
    :param relationship_model:
    :param entity_model:
    :param operation:
    :return:
    """
    if not id_list:
        return entity_model
    # e.g. CvMeasurementAttribute -> cv_measurement_attributes
    relationship_label, relationship = 
get_relationship_from_model(parent_entity=entity_model,
                                                                   
relationship_model=relationship_model)
    entities_to_relate = [
        type_query(type=relationship_model, id=id_) for id_ in id_list
    ]
    if operation == "add":
        relationship.extend(entities_to_relate)
    elif operation == "remove":
        for entity in entities_to_relate:
            relationship.remove(entity)
    else:
        setattr(entity_model, relationship_label, entities_to_relate)
    return entity_model



-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/323bfe66-3d7d-4fe1-87cf-feb4ca9566bfo%40googlegroups.com.

Reply via email to