MicroStrategy / mstrio-py

Python integration for MicroStrategy
Apache License 2.0
90 stars 60 forks source link

list_dependents uses_recursive goes down to table then back up, returning objects that are not true dependents #118

Closed hustontrevor closed 1 year ago

hustontrevor commented 1 year ago

Microstrategy does this everywhere it does recursive dependencies, but I'm wondering if there is some setting to avoid it that I have not found yet?

If you have a Fact object and you want to see which reports need it, when you do a recursive dependency search you will get a list that includes all the Attributes that came from the same tables and all their reports regardless of whether the Fact - Metric is used.

Below is my workaround, but it is extremely slow. Doing maybe two objects a second.

The full recursive search is very fast, but has tons of irrelevant objects and no real way to differentiate what is a dependent of the object and what is a dependent of the table that is a component of the object.

def getDirectDependents(depns, obj, depth):
# !! Attribute.list_dependents(uses_recursive=True) goes down to Table then back up, so it's useless. Need one at a time loop
# don't let higher schema objects drop back down to table level
# want to avoid flow like table - attribute - fact - table - ... everything else dependent on the table
# example: 31 dbconn/29 dbinstance/15 table1/12 attribute1/15 table2/13 fact2/4 Metric2/3 Report2/
# Report2 is not an actual dependent of attribute1.

    dependents = obj.list_dependents(uses_recursive=False,to_dictionary=False)    
    for d in dependents:
        # Not Schema or Schema Hierarchy
        if d not in depns and not ( d.id == 'A92B4BC0131145A0A2BE3DCD5D77F57C' or d.id == 'FD107ADDE8A948AE80F794A288FA70F4' ):
            # Not a Table if we're already above Tables
            if not ( obj.type.value in [1,3,12,13] and d.type.value == 15 ):   
                if not any(d.id == lst.id for lst in depns):
                    #print(str(depth) + ' - ' + str(d.type.value) + ' - ' + d.name)             
                    getDirectDependents(depns, d, depth+1, project_id)
                    d.depth = depth
                    depns.append(d)
    return depns
urszulajaczewska commented 1 year ago

Hi @hustontrevor, unfortunately your solution is the only possible one at the moment. If there are any changes in endpoints, we'll investigate it further.