MicroStrategy / mstrio-py

Python integration for MicroStrategy
Apache License 2.0
89 stars 57 forks source link

filter.alter does not work well with custom expressions #167

Open vladbaja opened 5 months ago

vladbaja commented 5 months ago

We have a complex hierarchy of filters and prompts. One of the filters is an AND between 2 filters and 1 prompt. Since we create them by a setup pythong script, we use custom expressions to handle easily. Creating the filter works, but updating it (even with the same expression) does not work. The server returns a weird error about an ID that is 0. We found a workaround that setting {} as the qualification before the actual update works, BUT when the filter has many dependents (there are about 6 filters depending on it and tens of dossiers), the update returns timeout.

We do something along the lines:

        expression = self.create_expression_from_formula(filter_formula)
        my_filter.alter(
            description=filter_description,
            qualification=expression
        )

Where the expression is build like this:

        expression_text = ' AND '.join(filter_formula.children)

        custom_expressions = []
        for child_formula in filter_formula.children:
            custom_expressions.append(CustomExpressionPredicate(expression=self.create_expression_from_string(child_formula)))

        return Expression(
            text=expression_text,
            tree=Operator(children = custom_expressions,
                           function = Function.AND)
        )

And create_expression_from_string returns:

        Expression(
            text=formula,
            tokens=[
                Token(
                    value = '%',
                    type=Token.Type.CHARACTER,
                    level=Token.Level.PARSED,
                    state=Token.State.OKAY,
                ),
                Token(
                    value = formula,
                    type=Token.Type.UNKNOWN,
                    level=Token.Level.CLIENT,
                    state=Token.State.INITIAL,
                ),
                Token(
                    value='',
                    type=Token.Type.END_OF_TEXT,
                    level=Token.Level.PARSED,
                    state=Token.State.OKAY,
                ),
            ]
        )

and children is a list of strings:

        "children": [
            "?[Product Prompt]",
            "?[Area Prompt]",
            "[Start Time (First Run)]@ID Between ?[Start Date Prompt] and ?[End Date Prompt]"
        ]