pydpm_xl 0.1.10__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. py_dpm/AST/ASTConstructor.py +503 -0
  2. py_dpm/AST/ASTObjects.py +827 -0
  3. py_dpm/AST/ASTTemplate.py +101 -0
  4. py_dpm/AST/ASTVisitor.py +13 -0
  5. py_dpm/AST/MLGeneration.py +588 -0
  6. py_dpm/AST/ModuleAnalyzer.py +79 -0
  7. py_dpm/AST/ModuleDependencies.py +203 -0
  8. py_dpm/AST/WhereClauseChecker.py +12 -0
  9. py_dpm/AST/__init__.py +0 -0
  10. py_dpm/AST/check_operands.py +302 -0
  11. py_dpm/DataTypes/ScalarTypes.py +324 -0
  12. py_dpm/DataTypes/TimeClasses.py +370 -0
  13. py_dpm/DataTypes/TypePromotion.py +195 -0
  14. py_dpm/DataTypes/__init__.py +0 -0
  15. py_dpm/Exceptions/__init__.py +0 -0
  16. py_dpm/Exceptions/exceptions.py +84 -0
  17. py_dpm/Exceptions/messages.py +114 -0
  18. py_dpm/OperationScopes/OperationScopeService.py +247 -0
  19. py_dpm/OperationScopes/__init__.py +0 -0
  20. py_dpm/Operators/AggregateOperators.py +138 -0
  21. py_dpm/Operators/BooleanOperators.py +30 -0
  22. py_dpm/Operators/ClauseOperators.py +159 -0
  23. py_dpm/Operators/ComparisonOperators.py +69 -0
  24. py_dpm/Operators/ConditionalOperators.py +362 -0
  25. py_dpm/Operators/NumericOperators.py +101 -0
  26. py_dpm/Operators/Operator.py +388 -0
  27. py_dpm/Operators/StringOperators.py +27 -0
  28. py_dpm/Operators/TimeOperators.py +53 -0
  29. py_dpm/Operators/__init__.py +0 -0
  30. py_dpm/Utils/ValidationsGenerationUtils.py +429 -0
  31. py_dpm/Utils/__init__.py +0 -0
  32. py_dpm/Utils/operands_mapping.py +73 -0
  33. py_dpm/Utils/operator_mapping.py +89 -0
  34. py_dpm/Utils/tokens.py +172 -0
  35. py_dpm/Utils/utils.py +2 -0
  36. py_dpm/ValidationsGeneration/PropertiesConstraintsProcessor.py +190 -0
  37. py_dpm/ValidationsGeneration/Utils.py +364 -0
  38. py_dpm/ValidationsGeneration/VariantsProcessor.py +265 -0
  39. py_dpm/ValidationsGeneration/__init__.py +0 -0
  40. py_dpm/ValidationsGeneration/auxiliary_functions.py +98 -0
  41. py_dpm/__init__.py +61 -0
  42. py_dpm/api/__init__.py +140 -0
  43. py_dpm/api/ast_generator.py +438 -0
  44. py_dpm/api/complete_ast.py +241 -0
  45. py_dpm/api/data_dictionary_validation.py +577 -0
  46. py_dpm/api/migration.py +77 -0
  47. py_dpm/api/semantic.py +224 -0
  48. py_dpm/api/syntax.py +182 -0
  49. py_dpm/client.py +106 -0
  50. py_dpm/data_handlers.py +99 -0
  51. py_dpm/db_utils.py +117 -0
  52. py_dpm/grammar/__init__.py +0 -0
  53. py_dpm/grammar/dist/__init__.py +0 -0
  54. py_dpm/grammar/dist/dpm_xlLexer.interp +428 -0
  55. py_dpm/grammar/dist/dpm_xlLexer.py +804 -0
  56. py_dpm/grammar/dist/dpm_xlLexer.tokens +106 -0
  57. py_dpm/grammar/dist/dpm_xlParser.interp +249 -0
  58. py_dpm/grammar/dist/dpm_xlParser.py +5224 -0
  59. py_dpm/grammar/dist/dpm_xlParser.tokens +106 -0
  60. py_dpm/grammar/dist/dpm_xlParserListener.py +742 -0
  61. py_dpm/grammar/dist/dpm_xlParserVisitor.py +419 -0
  62. py_dpm/grammar/dist/listeners.py +10 -0
  63. py_dpm/grammar/dpm_xlLexer.g4 +435 -0
  64. py_dpm/grammar/dpm_xlParser.g4 +260 -0
  65. py_dpm/migration.py +282 -0
  66. py_dpm/models.py +2139 -0
  67. py_dpm/semantics/DAG/DAGAnalyzer.py +158 -0
  68. py_dpm/semantics/DAG/__init__.py +0 -0
  69. py_dpm/semantics/SemanticAnalyzer.py +320 -0
  70. py_dpm/semantics/Symbols.py +223 -0
  71. py_dpm/semantics/__init__.py +0 -0
  72. py_dpm/utils/__init__.py +0 -0
  73. py_dpm/utils/ast_serialization.py +481 -0
  74. py_dpm/views/data_types.sql +12 -0
  75. py_dpm/views/datapoints.sql +65 -0
  76. py_dpm/views/hierarchy_operand_reference.sql +11 -0
  77. py_dpm/views/hierarchy_preconditions.sql +13 -0
  78. py_dpm/views/hierarchy_variables.sql +26 -0
  79. py_dpm/views/hierarchy_variables_context.sql +14 -0
  80. py_dpm/views/key_components.sql +18 -0
  81. py_dpm/views/module_from_table.sql +11 -0
  82. py_dpm/views/open_keys.sql +13 -0
  83. py_dpm/views/operation_info.sql +27 -0
  84. py_dpm/views/operation_list.sql +18 -0
  85. py_dpm/views/operations_versions_from_module_version.sql +30 -0
  86. py_dpm/views/precondition_info.sql +17 -0
  87. py_dpm/views/report_type_operand_reference_info.sql +18 -0
  88. py_dpm/views/subcategory_info.sql +17 -0
  89. py_dpm/views/table_info.sql +19 -0
  90. pydpm_xl-0.1.10.dist-info/LICENSE +674 -0
  91. pydpm_xl-0.1.10.dist-info/METADATA +50 -0
  92. pydpm_xl-0.1.10.dist-info/RECORD +94 -0
  93. pydpm_xl-0.1.10.dist-info/WHEEL +4 -0
  94. pydpm_xl-0.1.10.dist-info/entry_points.txt +3 -0
py_dpm/Utils/tokens.py ADDED
@@ -0,0 +1,172 @@
1
+ # Comparison operators.
2
+ EQ = '='
3
+ NEQ = '!='
4
+ GT = '>'
5
+ GTE = '>='
6
+ LT = '<'
7
+ LTE = '<='
8
+ IN = 'in'
9
+ ISNULL = 'isnull'
10
+ MATCH = 'match'
11
+
12
+ # Numeric operators
13
+ PLUS = '+'
14
+ MINUS = '-'
15
+ MULT = '*'
16
+ DIV = '/'
17
+ ABS = 'abs'
18
+ EXP = 'exp'
19
+ LN = 'ln'
20
+ SQRT = 'sqrt'
21
+ POW = 'power'
22
+ LOG = 'log'
23
+ MAX = 'max'
24
+ MIN = 'min'
25
+
26
+ # Boolean operators.
27
+ AND = 'and'
28
+ OR = 'or'
29
+ XOR = 'xor'
30
+ NOT = 'not'
31
+
32
+ # Conditional operators.
33
+ IF = "if"
34
+ NVL= "nvl"
35
+
36
+ # Clause operators
37
+ WHERE = 'where'
38
+ RENAME = 'rename'
39
+ GET = 'get'
40
+
41
+ # Aggregation operators
42
+ MAX_AGGR = 'max_aggr'
43
+ MIN_AGGR = 'min_aggr'
44
+ SUM = 'sum'
45
+ COUNT = 'count'
46
+ AVG = 'avg'
47
+ MEDIAN = 'median'
48
+
49
+ # String operators
50
+ LENGTH = "len"
51
+ CONCATENATE = "&"
52
+
53
+ # Time operators
54
+ TIME_SHIFT = 'time_shift'
55
+
56
+ # Conditional operators
57
+ FILTER = 'filter'
58
+
59
+ # key Components types
60
+ DPM = "DPM"
61
+ STANDARD = "Standard"
62
+
63
+ # Standard key names
64
+ ROW = 'r'
65
+ COLUMN = 'c'
66
+ SHEET = 's'
67
+ FACT = 'f'
68
+
69
+ # Indexes
70
+ INDEX_X = 'x'
71
+ INDEX_Y = 'y'
72
+ INDEX_Z = 'z'
73
+
74
+ # Cell components
75
+ ROW_CODE = 'row_code'
76
+ COLUMN_CODE = 'column_code'
77
+ SHEET_CODE = 'sheet_code'
78
+ TABLE_CODE = 'table_code'
79
+ CELL_COMPONENTS = [ROW_CODE, COLUMN_CODE, SHEET_CODE]
80
+
81
+ # Generated validations status
82
+ STATUS = 'status'
83
+ STATUS_CORRECT = 'Correct'
84
+ STATUS_INCORRECT = 'Incorrect'
85
+ STATUS_INCOMPLETE = 'Incomplete'
86
+ STATUS_UNKNOWN = 'Unknown'
87
+ TABLE_VERSION_ID = 'table_version_id'
88
+
89
+ # Generated validations constants
90
+ ITEM_ID = 'ItemID'
91
+ PARENT_ITEM_ID = 'ParentItemID'
92
+ VARIABLE_VID = 'variable_vid'
93
+ ARITHMETIC_OPERATOR_ID = 'ArithmeticOperatorID'
94
+ ORDER = 'Order'
95
+
96
+ TABLE_CODE_LEFT = TABLE_CODE + '_left'
97
+ ROW_CODE_LEFT = ROW_CODE + '_left'
98
+ COLUMN_CODE_LEFT = COLUMN_CODE + '_left'
99
+ SHEET_CODE_LEFT = SHEET_CODE + '_left'
100
+
101
+ TABLE_CODE_RIGHT = TABLE_CODE + '_right'
102
+ ROW_CODE_RIGHT = ROW_CODE + '_right'
103
+ COLUMN_CODE_RIGHT = COLUMN_CODE + '_right'
104
+ SHEET_CODE_RIGHT = SHEET_CODE + '_right'
105
+ VARIABLE_PROPERTY_ID = 'variable_property_id'
106
+
107
+ CONTEXT_PROPERTY = 'context_property'
108
+ OPERATOR_ID = 'OperatorID'
109
+ SYMBOL = 'Symbol'
110
+ ARITHMETIC_OPERATOR_SYMBOL = 'arithmetic_operator_symbol'
111
+ COMPARISON_OPERATOR_ID = 'ComparisonOperatorID'
112
+ COMPARISON_OPERATOR_SYMBOL = 'comparison_operator_symbol'
113
+
114
+ OPERATOR = 'operator'
115
+ IS_DEFAULT_ITEM = 'IsDefaultItem'
116
+ PROPERTY_ID = 'property_id'
117
+ CONTEXT_ITEM = 'context_item'
118
+ CONTEXT_ITEM_ID = 'context_item_id'
119
+ METRIC_PROPERTY_ID = 'metric_property_id'
120
+ CONTEXT_PROPERTY_ID = 'context_property_id'
121
+ SUBCATEGORY_PROPERTY = 'subcategory_property'
122
+
123
+ VALIDATION_CODE = 'validation_code'
124
+ TABLE_GROUP_CHILD_TYPE = 'tableGroup_child'
125
+ EXPRESSION = 'expression'
126
+ DUPLICATE_VARIABLES = 'duplicate_variables'
127
+ CELL_ID = 'cell_id'
128
+ SUBCATEGORY_ID = 'subcategory_id'
129
+ SUBCATEGORY_CODE = 'subcategory_code'
130
+ PARENT_ID = 'parent_id'
131
+ LEFT_CELL_IDS = 'left_cell_ids'
132
+ KEY_ID = 'KeyID'
133
+
134
+ # Data types
135
+ PER = "p"
136
+
137
+ INPUTS = 'inputs'
138
+ OUTPUTS = 'outputs'
139
+
140
+ # Prefix
141
+ TABLE_GROUP_PREFIX = 'g'
142
+
143
+ # Modules
144
+ INTRA_MODULE = 'intra-module'
145
+ CROSS_MODULE = 'cross-module'
146
+ REPEATED_INTRA_MODULE = 'repeated-intra-module'
147
+ REPEATED_CROSS_MODULE = 'repeated-cross-module'
148
+
149
+ # Operation scope constants
150
+ WARNING_SEVERITY = 'warning'
151
+
152
+ FILING_INDICATOR = 'filingIndicator'
153
+ OP_VERSION_ID = 'op_version_id'
154
+
155
+ # Report types
156
+ HIERARCHY_REPORT = 'hierarchy_report'
157
+ SIGN_REPORT = 'sign_report'
158
+ EXISTENCE_REPORT = 'existence_report'
159
+ HIERARCHY = 'hierarchy'
160
+ SIGN = 'sign'
161
+ EXISTENCE = 'existence'
162
+ #sign
163
+ POSITIVE = 'positive'
164
+ NEGATIVE = 'negative'
165
+
166
+ # Web service constants
167
+ CODE = 'code'
168
+ ERROR = 'error'
169
+ ERROR_CODE = 'error_code'
170
+ VALIDATIONS = 'validations'
171
+ VARIABLES = 'variables'
172
+ VALIDATION_TYPE = 'validation_type'
py_dpm/Utils/utils.py ADDED
@@ -0,0 +1,2 @@
1
+ START_RELEASE_ID_EBA = None
2
+ START_RELEASE_ID_EIOPA = 1020000001
@@ -0,0 +1,190 @@
1
+ import pandas as pd
2
+
3
+ from py_dpm.AST.ASTObjects import AggregationOp, BinOp, ComplexNumericOp, CondExpr, FilterOp, GetOp, PropertyReference, RenameOp, Scalar, \
4
+ TimeShiftOp, UnaryOp, VarID, WhereClauseOp
5
+ from py_dpm.AST.ASTTemplate import ASTTemplate
6
+ from py_dpm.Exceptions import exceptions
7
+ from py_dpm.models import ItemCategory, ViewDatapoints
8
+ from py_dpm.Utils.ValidationsGenerationUtils import ValidationsGenerationUtils
9
+ from py_dpm.Utils.tokens import *
10
+
11
+ ALLOWED_OPERATORS = [MATCH, IN, EQ, NEQ, GT, GTE, LT, LTE, LENGTH, CONCATENATE]
12
+
13
+
14
+ def _check_property_constraint_exists(signature: str, session):
15
+ if ":" in signature:
16
+ property_query = ItemCategory.get_property_from_signature(signature, session)
17
+ else:
18
+ property_query = ItemCategory.get_property_from_code(signature, session)
19
+ if property_query is None:
20
+ return False
21
+ return True
22
+
23
+
24
+ class PropertiesConstraintsChecker(ASTTemplate):
25
+ def __init__(self, ast, session):
26
+ super().__init__()
27
+ self.has_property = False
28
+ self.has_table = False
29
+ self.session = session
30
+ self.visit(ast)
31
+
32
+ @property
33
+ def is_property_constraint(self):
34
+ if self.has_table:
35
+ return False
36
+ return self.has_property
37
+
38
+ def visit_PropertyReference(self, node: PropertyReference):
39
+ # Optional
40
+ if not ":" in node.code:
41
+ pass # signature should have : to be a property constraint
42
+ signature = node.code
43
+ # look for property in models
44
+ property_query = ItemCategory.get_property_from_signature(signature, self.session)
45
+ if property_query is None:
46
+ raise exceptions.SemanticError("5-1-4", ref=signature)
47
+ self.has_property = True
48
+
49
+ def visit_VarID(self, node: VarID):
50
+ if node.table:
51
+ self.has_table = True
52
+
53
+ def visit_Scalar(self, node: Scalar):
54
+ signature = node.item
55
+ if not self.has_property:
56
+ if getattr(node, "scalar_type", None) == "Item":
57
+ # go to models and check if item exists and is a property
58
+ property_query = ItemCategory.get_property_from_signature(signature, self.session)
59
+ if property_query:
60
+ self.has_property = True
61
+ # other assumption could be always first scalar is a property but this is not true
62
+ # self.has_property = True
63
+ else:
64
+ other_property_query = ItemCategory.get_property_from_signature(signature, self.session)
65
+ if other_property_query:
66
+ raise exceptions.SemanticError("5-1-2")
67
+
68
+
69
+ class PropertiesConstraintsProcessor(ASTTemplate):
70
+ """
71
+ Class to generate individual validations from properties constraints
72
+
73
+ :parameter expression: DPM-XL expression.
74
+ :parameter ast: Abstract Syntax Tree of expression.
75
+ :parameter validation_code: Code of parent validation.
76
+ :parameter session: SQLAlchemy Session to be used to connect to the DB.
77
+ """
78
+
79
+ def __init__(self, expression, ast, validation_code, session, release_id):
80
+ super().__init__()
81
+ self.expression = expression
82
+ self.AST = ast
83
+ self.validation_code = validation_code
84
+ self.session = session
85
+ self.current_validation = 1
86
+ self.property_constraint = None
87
+ self.release_id = release_id
88
+ self.new_expressions = []
89
+ self.visit(self.AST)
90
+
91
+ def generate_validations(self):
92
+ """
93
+ Generates individual validations using the extracted property constraint in the Abstract Syntax Tree
94
+ """
95
+ if not self.property_constraint:
96
+ raise exceptions.SemanticError("5-1-1")
97
+
98
+ item_category = ItemCategory.get_property_from_signature(
99
+ signature=self.property_constraint, session=self.session, release_id=self.release_id)
100
+ if item_category is None:
101
+ raise exceptions.SemanticError("1-7", property_code=self.property_constraint)
102
+ variables: pd.DataFrame = ViewDatapoints.get_from_property(self.session, item_category.ItemID, self.release_id)
103
+ for table_code, group_df in variables.groupby(['table_code']):
104
+ datapoints = ViewDatapoints.get_table_data(session=self.session, table=str(table_code))
105
+ self.generate_expressions(table_code, group_df, datapoints)
106
+
107
+ def generate_expressions(self, table_code, data, datapoints_table):
108
+ """
109
+ Generates new expressions getting their operands by grouping the cells
110
+ :param table_code: code of the operand table
111
+ :param data: dataframe with operand datapoints
112
+ :param datapoints_table: table datapoints
113
+ """
114
+ groups = ValidationsGenerationUtils.group_cells(datapoints_variable=data,
115
+ datapoints_table=datapoints_table)
116
+ for rows, cols, sheets in groups:
117
+ operand = ValidationsGenerationUtils.write_cell(table_code, rows, cols, sheets)
118
+ new_expression = self.expression
119
+ new_expression = new_expression.replace(f"[{self.property_constraint}]", operand)
120
+ self.new_expressions.append(new_expression)
121
+
122
+ def create_validation(self, expression, status):
123
+ """
124
+ Creates a dictionary to represent a validation from expression and status information
125
+ :param expression: Expression of validation
126
+ :param status: Status of validation
127
+ :return a dictionary with validation_code, expression and status
128
+ """
129
+ validation_code = None
130
+ if status == STATUS_CORRECT:
131
+ validation_code = f"{self.validation_code}-{self.current_validation}"
132
+ self.current_validation += 1
133
+ return {
134
+ VALIDATION_CODE: validation_code,
135
+ EXPRESSION: expression,
136
+ STATUS: status
137
+ }
138
+
139
+ def visit_PropertyReference(self, node: PropertyReference):
140
+ if not self.property_constraint:
141
+ self.property_constraint = node.code
142
+ signature = node.code
143
+ if not _check_property_constraint_exists(signature, self.session):
144
+ raise exceptions.SemanticError("5-1-4", ref=signature)
145
+ else:
146
+ raise exceptions.SemanticError("5-1-2")
147
+
148
+ def visit_Scalar(self, node: Scalar):
149
+ if getattr(node, "scalar_type", None) == "Item":
150
+ signature = node.item
151
+ property_query = ItemCategory.get_property_from_signature(signature, self.session)
152
+ if property_query:
153
+ if not self.property_constraint:
154
+ self.property_constraint = signature
155
+
156
+ def visit_BinOp(self, node: BinOp):
157
+ if node.op not in ALLOWED_OPERATORS:
158
+ raise exceptions.SemanticError("5-1-3", operator=node.op)
159
+
160
+ self.visit(node.left)
161
+ self.visit(node.right)
162
+
163
+ def visit_UnaryOp(self, node: UnaryOp):
164
+ if node.op not in ALLOWED_OPERATORS:
165
+ raise exceptions.SemanticError("5-1-3", operator=node.op)
166
+ self.visit(node.operand)
167
+
168
+ def visit_CondExpr(self, node: CondExpr):
169
+ raise exceptions.SemanticError("5-1-3", operator=IF)
170
+
171
+ def visit_AggregationOp(self, node: AggregationOp):
172
+ raise exceptions.SemanticError("5-1-3", operator=node.op)
173
+
174
+ def visit_RenameOp(self, node: RenameOp):
175
+ raise exceptions.SemanticError("5-1-3", operator=RENAME)
176
+
177
+ def visit_TimeShiftOp(self, node: TimeShiftOp):
178
+ raise exceptions.SemanticError("5-1-3", operator=TIME_SHIFT)
179
+
180
+ def visit_FilterOp(self, node: FilterOp):
181
+ raise exceptions.SemanticError("5-1-3", operator=FILTER)
182
+
183
+ def visit_WhereClauseOp(self, node: WhereClauseOp):
184
+ raise exceptions.SemanticError("5-1-3", operator=WHERE)
185
+
186
+ def visit_GetOp(self, node: GetOp):
187
+ raise exceptions.SemanticError("5-1-3", operator=GET)
188
+
189
+ def visit_ComplexNumericOp(self, node: ComplexNumericOp):
190
+ raise exceptions.SemanticError("5-1-3", operator=node.op)