-
Notifications
You must be signed in to change notification settings - Fork 0
Relational variable management
Throughout the model execution process we use PyRAL to set relational variables which, are in fact, tcl variables in TclRAL.
For example, we might want to look up information about the executing Lifecycle State Activity and save it for future reference.
So we use PyRAL to restrict the appropriate Lifecycle_Activity relvar on an Anum (activity number) and domain (domain name).
R = f"Anum:<{anum}>, Domain:<{self.state_machine.domain.name}>" # Compose the restriction as a string
Relation.restrict(db=mmdb, relation='Lifecycle Activity', restriction=R) # Provide it to the PyRAL restrict method
lifecycle_activity_r = Relation.rename(db=mmdb, names={"Anum": "Activity"}, svar_name=rv_name) # Save result as python variableThis yields a relation with a single tuple representing information about our Lifecycle Activity, like this:
-- Lifecycle_Activity --
+--------+---------------------+---------------------------+
| Anum | Domain | Executing_instance_flow |
+========+=====================+===========================+
| A40 | Elevator Management | F1 |
+--------+---------------------+---------------------------+
We could just save the result of that query in a python structure.
And in the last line of the code above, we have assigned this result to the lifecycle_activity_r python variable. (by convention, I use the _r suffix to indicate that the variable holds a relational result). This is useful when we want to pick data out of any returned tuples. For example, we might want to grab the label of the executing instance flow (the instance executing our activity) and save it as a python variable.
Here's the complete result saved in a python variable with a header and body dictionary.
RelationValue(name='^relation', header={'Anum': 'string', 'Domain': 'string', 'Executing_instance_flow': 'string'}, body=[{'Anum': 'A40', 'Domain': 'Elevator Management', 'Executing_instance_flow': 'F1'}])
You can see the header and body components of the relation in the structure above. You might also notice the ^relation name at the beginning. We'll get to that first part later on, so try to ignore it for now.
Assuming a single tuple, as we have here, we can grab the label like so:
xi_flow_name = lifecycle_activity_r.body[0]['Executing_instance_flow']And our variable xi_flow_name would hold the string 'F1'.
But we often want to retain the original query result as a relation variable in TclRAL so that we can use it as a jumping point for more queries. We may want, for example, to apply the rename operation in preparation for doing a semijoin with some other metamodel class relvar. TclRAL can't do anything with our python variable, but we can tell TclRAL, via PyRAL, to save the query result using some relational variable name of our choosing. Later we can instruct TclRAL to input that variable into further relational operations.
So let's change our code accordingly:
R = f"Anum:<{anum}>, Domain:<{self.state_machine.domain.name}>"
Relation.restrict(db=mmdb, relation='Lifecycle Activity', restriction=R)
lifecycle_activity_r = Relation.rename(db=mmdb, names={"Anum": "Activity"}, svar_name=rv_name)Note that the second line is no longer assigned to a python _r variable. We just perform the restrict operation, but where is the result?
PyRAL automatically saves the result of each query using the TclRAL variable ^relation that I told you to ignore earlier. Scroll back up and and take a look. PyRAL saves the output of its latest query in the Tcl ^relation variable. So ^relation is the default input relation to any query with no specified input relation.
In our example above, the Relation.rename method does not specify any relation= value, so it just takes the output of our restrict as input. But note that we have added an svar_name parameter. If we specify an svar_, we are telling PyRAL to instead save the query result using that variable name.
So during the process of model execution, we could just create as many temporary relational variables as we need, but sooner or later we're going to run into trouble.
Let's put aside the obvious problem that we'll eventually lose track
... to be continued 26-3-15 / LS
Copyright © 2025-2026, Leon Starr at Model Integration, LLC under the MIT Open Source License