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/models.py ADDED
@@ -0,0 +1,2139 @@
1
+ from datetime import datetime
2
+ from typing import List
3
+ from sqlalchemy import (
4
+ Boolean, Column, Date, DateTime, ForeignKey, Integer, String, Text, and_,
5
+ SmallInteger, and_, or_, select, UniqueConstraint
6
+ )
7
+ from sqlalchemy.dialects.postgresql import UUID
8
+ from sqlalchemy.orm import aliased, declarative_base, relationship
9
+ from sqlalchemy import func
10
+ import pandas as pd
11
+
12
+ Base = declarative_base()
13
+
14
+ class AuxCellmapping(Base):
15
+ __tablename__ = "Aux_CellMapping"
16
+
17
+ newcellid = Column("NewCellID", Integer, primary_key=True)
18
+ newtablevid = Column("NewTableVID", Integer, primary_key=True)
19
+ oldcellid = Column("OldCellID", Integer)
20
+ oldtablevid = Column("OldTableVID", Integer)
21
+
22
+ __table_args__ = (
23
+ UniqueConstraint('NewCellID', 'NewTableVID'),
24
+ )
25
+
26
+ class AuxCellstatus(Base):
27
+ __tablename__ = "Aux_CellStatus"
28
+
29
+ tablevid = Column("TableVID", Integer, primary_key=True)
30
+ cellid = Column("CellID", Integer, primary_key=True)
31
+ status = Column("Status", String(100))
32
+ isnewcell = Column("IsNewCell", Boolean)
33
+
34
+ __table_args__ = (
35
+ UniqueConstraint('TableVID', 'CellID'),
36
+ )
37
+
38
+ class Category(Base):
39
+ __tablename__ = "Category"
40
+
41
+ categoryid = Column("CategoryID", Integer, primary_key=True)
42
+ code = Column("Code", String(20))
43
+ name = Column("Name", String(50))
44
+ description = Column("Description", String(1000))
45
+ isenumerated = Column("IsEnumerated", Boolean)
46
+ issupercategory = Column("IsSuperCategory", Boolean)
47
+ isactive = Column("IsActive", Boolean)
48
+ isexternalrefdata = Column("IsExternalRefData", Boolean)
49
+ refdatasource = Column("RefDataSource", String(255))
50
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
51
+
52
+ # Use string references instead of direct class references
53
+ concept = relationship("Concept", foreign_keys=[rowguid])
54
+ subcategories = relationship("SubCategory", back_populates="category") # Note: SubCategory not Subcategory
55
+ property_categories = relationship("PropertyCategory", back_populates="category")
56
+ supercategory_compositions = relationship("SupercategoryComposition",
57
+ foreign_keys="SupercategoryComposition.supercategoryid",
58
+ back_populates="supercategory")
59
+ category_compositions = relationship("SupercategoryComposition",
60
+ foreign_keys="SupercategoryComposition.categoryid",
61
+ back_populates="category")
62
+
63
+ class SubCategory(Base):
64
+ __tablename__ = "SubCategory"
65
+
66
+ subcategoryid = Column("SubCategoryID", Integer, primary_key=True)
67
+ categoryid = Column("CategoryID", Integer, ForeignKey("Category.CategoryID"))
68
+ code = Column("Code", String(30))
69
+ name = Column("Name", String(500))
70
+ description = Column("Description", String(500))
71
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
72
+
73
+ # Relationships
74
+ category = relationship("Category", back_populates="subcategories")
75
+ concept = relationship("Concept", foreign_keys=[rowguid])
76
+ subcategory_versions = relationship("SubCategoryVersion", back_populates="subcategory")
77
+ operand_references = relationship("OperandReference", back_populates="subcategory")
78
+ class Cell(Base):
79
+ __tablename__ = "Cell"
80
+
81
+ cellid = Column("CellID", Integer, primary_key=True)
82
+ tableid = Column("TableID", Integer, ForeignKey("Table.TableID"))
83
+ columnid = Column("ColumnID", Integer, ForeignKey("Header.HeaderID"))
84
+ rowid = Column("RowID", Integer, ForeignKey("Header.HeaderID"))
85
+ sheetid = Column("SheetID", Integer, ForeignKey("Header.HeaderID"))
86
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
87
+
88
+ # Relationships
89
+ table = relationship("Table", foreign_keys=[tableid])
90
+ column_header = relationship("Header", foreign_keys=[columnid])
91
+ row_header = relationship("Header", foreign_keys=[rowid])
92
+ sheet_header = relationship("Header", foreign_keys=[sheetid])
93
+ concept = relationship("Concept", foreign_keys=[rowguid])
94
+ table_version_cells = relationship("TableVersionCell", back_populates="cell")
95
+ operand_reference_locations = relationship("OperandReferenceLocation", back_populates="cell")
96
+
97
+ __table_args__ = (
98
+ UniqueConstraint('ColumnID', 'RowID', 'SheetID'),
99
+ )
100
+
101
+ class Changelog(Base):
102
+ __tablename__ = "ChangeLog"
103
+
104
+ rowguid = Column("RowGUID", String(36), primary_key=True)
105
+ classid = Column("ClassID", Integer, ForeignKey("DPMClass.ClassID"), primary_key=True)
106
+ attributeid = Column("AttributeID", Integer, ForeignKey("DPMAttribute.AttributeID"), primary_key=True)
107
+ timestamp = Column("Timestamp", Integer, primary_key=True)
108
+ oldvalue = Column("OldValue", String(255))
109
+ newvalue = Column("NewValue", String(255))
110
+ changetype = Column("ChangeType", String(20))
111
+ status = Column("Status", String(1))
112
+ userid = Column("UserID", Integer, ForeignKey("User.UserID"))
113
+ releaseid = Column("ReleaseID", Integer, ForeignKey("Release.ReleaseID"))
114
+
115
+ # Relationships
116
+ dpm_class = relationship("DpmClass", foreign_keys=[classid])
117
+ dpm_attribute = relationship("DpmAttribute", foreign_keys=[attributeid])
118
+ user = relationship("User", foreign_keys=[userid])
119
+ release = relationship("Release", foreign_keys=[releaseid])
120
+
121
+ class CompoundItemContext(Base):
122
+ __tablename__ = "CompoundItemContext"
123
+
124
+ itemid = Column("ItemID", Integer, ForeignKey("Item.ItemID"), primary_key=True)
125
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"), primary_key=True)
126
+ contextid = Column("ContextID", Integer, ForeignKey("Context.ContextID"))
127
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
128
+ rowguid = Column("RowGUID", String(36))
129
+
130
+ # Relationships
131
+ item = relationship("Item", foreign_keys=[itemid])
132
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
133
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
134
+ context = relationship("Context", foreign_keys=[contextid])
135
+
136
+ class CompoundKey(Base):
137
+ __tablename__ = "CompoundKey"
138
+
139
+ keyid = Column("KeyID", Integer, primary_key=True)
140
+ signature = Column("Signature", String(255), unique=True)
141
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
142
+
143
+ # Relationships
144
+ concept = relationship("Concept", foreign_keys=[rowguid])
145
+ key_compositions = relationship("KeyComposition", back_populates="compound_key")
146
+ module_versions = relationship("ModuleVersion", back_populates="global_key")
147
+ table_versions = relationship("TableVersion", back_populates="key")
148
+
149
+ class Concept(Base):
150
+ __tablename__ = "Concept"
151
+
152
+ conceptguid = Column("ConceptGUID", String(36), primary_key=True)
153
+ classid = Column("ClassID", Integer, ForeignKey("DPMClass.ClassID"))
154
+ ownerid = Column("OwnerID", Integer, ForeignKey("Organisation.OrgID"))
155
+
156
+ # Relationships
157
+ dpm_class = relationship("DpmClass", foreign_keys=[classid])
158
+ owner = relationship("Organisation", foreign_keys=[ownerid])
159
+ related_concepts = relationship("RelatedConcept", back_populates="concept")
160
+ context_compositions = relationship("ContextComposition", back_populates="concept")
161
+
162
+ class ConceptRelation(Base):
163
+ __tablename__ = "ConceptRelation"
164
+
165
+ conceptrelationid = Column("ConceptRelationID", Integer, primary_key=True)
166
+ type = Column("Type", String(50))
167
+ rowguid = Column("RowGUID", String(36))
168
+
169
+ # Relationships
170
+ related_concepts = relationship("RelatedConcept", back_populates="concept_relation")
171
+
172
+ class Context(Base):
173
+ __tablename__ = "Context"
174
+
175
+ contextid = Column("ContextID", Integer, primary_key=True)
176
+ signature = Column("Signature", String(2000), unique=True)
177
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
178
+
179
+ # Relationships
180
+ concept = relationship("Concept", foreign_keys=[rowguid])
181
+ context_compositions = relationship("ContextComposition", back_populates="context")
182
+ variable_versions = relationship("VariableVersion", back_populates="context")
183
+ header_versions = relationship("HeaderVersion", back_populates="context")
184
+ table_versions = relationship("TableVersion", back_populates="context")
185
+ compound_item_contexts = relationship("CompoundItemContext", back_populates="context")
186
+
187
+ class ContextComposition(Base):
188
+ __tablename__ = "ContextComposition"
189
+
190
+ contextid = Column("ContextID", Integer, ForeignKey("Context.ContextID"), primary_key=True)
191
+ propertyid = Column("PropertyID", Integer, ForeignKey("Property.PropertyID"), primary_key=True)
192
+ itemid = Column("ItemID", Integer, ForeignKey("Item.ItemID"))
193
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
194
+
195
+ # Relationships
196
+ context = relationship("Context", back_populates="context_compositions")
197
+ property = relationship("Property", back_populates="context_compositions")
198
+ item = relationship("Item", foreign_keys=[itemid])
199
+ concept = relationship("Concept", foreign_keys=[rowguid], back_populates="context_compositions")
200
+
201
+
202
+ class DpmAttribute(Base):
203
+ __tablename__ = "DPMAttribute"
204
+
205
+ attributeid = Column("AttributeID", Integer, primary_key=True)
206
+ classid = Column("ClassID", Integer, ForeignKey("DPMClass.ClassID"))
207
+ name = Column("Name", String(20))
208
+ hastranslations = Column("HasTranslations", Boolean)
209
+
210
+ # Relationships
211
+ dpm_class = relationship("DpmClass", back_populates="dpm_attributes")
212
+ changelogs = relationship("Changelog", back_populates="dpm_attribute")
213
+ translations = relationship("Translation", back_populates="dpm_attribute")
214
+
215
+ class DpmClass(Base):
216
+ __tablename__ = "DPMClass"
217
+
218
+ classid = Column("ClassID", Integer, primary_key=True)
219
+ name = Column("Name", String(50))
220
+ type = Column("Type", String(20))
221
+ ownerclassid = Column("OwnerClassID", Integer, ForeignKey("DPMClass.ClassID"))
222
+ hasreferences = Column("HasReferences", Boolean)
223
+
224
+ # Relationships
225
+ owner_class = relationship("DpmClass", remote_side=[classid], back_populates="owned_classes")
226
+ owned_classes = relationship("DpmClass", back_populates="owner_class")
227
+ concepts = relationship("Concept", back_populates="dpm_class")
228
+ dpm_attributes = relationship("DpmAttribute", back_populates="dpm_class")
229
+ changelogs = relationship("Changelog", back_populates="dpm_class")
230
+
231
+ class DataType(Base):
232
+ __tablename__ = "DataType"
233
+
234
+ datatypeid = Column("DataTypeID", Integer, primary_key=True)
235
+ code = Column("Code", String(20), unique=True)
236
+ name = Column("Name", String(50), unique=True)
237
+ parentdatatypeid = Column("ParentDataTypeID", Integer, ForeignKey("DataType.DataTypeID"))
238
+ isactive = Column("IsActive", Boolean)
239
+
240
+ # Relationships
241
+ parent_datatype = relationship("DataType", remote_side=[datatypeid], back_populates="child_datatypes")
242
+ child_datatypes = relationship("DataType", back_populates="parent_datatype")
243
+ properties = relationship("Property", back_populates="datatype")
244
+
245
+ class Document(Base):
246
+ __tablename__ = "Document"
247
+
248
+ documentid = Column("DocumentID", Integer, primary_key=True)
249
+ name = Column("Name", String(50))
250
+ code = Column("Code", String(20))
251
+ type = Column("Type", String(255))
252
+ orgid = Column("OrgID", Integer, ForeignKey("Organisation.OrgID"))
253
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
254
+
255
+ # Relationships
256
+ organisation = relationship("Organisation", foreign_keys=[orgid])
257
+ concept = relationship("Concept", foreign_keys=[rowguid])
258
+ document_versions = relationship("DocumentVersion", back_populates="document")
259
+
260
+ class DocumentVersion(Base):
261
+ __tablename__ = "DocumentVersion"
262
+
263
+ documentvid = Column("DocumentVID", Integer, primary_key=True)
264
+ documentid = Column("DocumentID", Integer, ForeignKey("Document.DocumentID"))
265
+ code = Column("Code", String(20))
266
+ version = Column("Version", String(20))
267
+ publicationdate = Column("PublicationDate", Date)
268
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
269
+
270
+ # Relationships
271
+ document = relationship("Document", back_populates="document_versions")
272
+ concept = relationship("Concept", foreign_keys=[rowguid])
273
+ subdivisions = relationship("Subdivision", back_populates="document_version")
274
+
275
+ __table_args__ = (
276
+ UniqueConstraint('DocumentID', 'PublicationDate'),
277
+ )
278
+
279
+ class Framework(Base):
280
+ __tablename__ = "Framework"
281
+
282
+ frameworkid = Column("FrameworkID", Integer, primary_key=True)
283
+ code = Column("Code", String(255))
284
+ name = Column("Name", String(255))
285
+ description = Column("Description", String(255))
286
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
287
+
288
+ # Relationships
289
+ concept = relationship("Concept", foreign_keys=[rowguid])
290
+ modules = relationship("Module", back_populates="framework")
291
+ operation_code_prefixes = relationship("OperationCodePrefix", back_populates="framework")
292
+
293
+ class Header(Base):
294
+ __tablename__ = "Header"
295
+
296
+ headerid = Column("HeaderID", Integer, primary_key=True)
297
+ tableid = Column("TableID", Integer, ForeignKey("Table.TableID"))
298
+ direction = Column("Direction", String(1))
299
+ iskey = Column("IsKey", Boolean)
300
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
301
+
302
+ # Relationships
303
+ table = relationship("Table", back_populates="headers")
304
+ concept = relationship("Concept", foreign_keys=[rowguid])
305
+ header_versions = relationship("HeaderVersion", back_populates="header")
306
+ column_cells = relationship("Cell", foreign_keys="Cell.columnid", back_populates="column_header")
307
+ row_cells = relationship("Cell", foreign_keys="Cell.rowid", back_populates="row_header")
308
+ sheet_cells = relationship("Cell", foreign_keys="Cell.sheetid", back_populates="sheet_header")
309
+
310
+ class HeaderVersion(Base):
311
+ __tablename__ = "HeaderVersion"
312
+
313
+ headervid = Column("HeaderVID", Integer, primary_key=True)
314
+ headerid = Column("HeaderID", Integer, ForeignKey("Header.HeaderID"))
315
+ code = Column("Code", String(10))
316
+ label = Column("Label", String(500))
317
+ propertyid = Column("PropertyID", Integer, ForeignKey("Property.PropertyID"))
318
+ contextid = Column("ContextID", Integer, ForeignKey("Context.ContextID"))
319
+ subcategoryvid = Column("SubCategoryVID", Integer, ForeignKey("SubCategoryVersion.SubCategoryVID"))
320
+ keyvariablevid = Column("KeyVariableVID", Integer, ForeignKey("VariableVersion.VariableVID"))
321
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
322
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
323
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
324
+
325
+ # Relationships
326
+ header = relationship("Header", back_populates="header_versions")
327
+ property = relationship("Property", foreign_keys=[propertyid])
328
+ context = relationship("Context", foreign_keys=[contextid])
329
+ subcategory_version = relationship("SubCategoryVersion", foreign_keys=[subcategoryvid])
330
+ key_variable_version = relationship("VariableVersion", foreign_keys=[keyvariablevid])
331
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
332
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
333
+ concept = relationship("Concept", foreign_keys=[rowguid])
334
+
335
+ __table_args__ = (
336
+ UniqueConstraint('HeaderID', 'StartReleaseID'),
337
+ )
338
+
339
+ class Item(Base):
340
+ __tablename__ = "Item"
341
+
342
+ itemid = Column("ItemID", Integer, primary_key=True)
343
+ name = Column("Name", String(500))
344
+ description = Column("Description", String(2000))
345
+ iscompound = Column("IsCompound", Boolean)
346
+ isproperty = Column("IsProperty", Boolean)
347
+ isactive = Column("IsActive", Boolean)
348
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
349
+
350
+ # Relationships - specify foreign_keys to resolve ambiguity
351
+ concept = relationship("Concept", foreign_keys=[rowguid])
352
+ item_categories = relationship("ItemCategory", back_populates="item")
353
+ property = relationship("Property", back_populates="item", uselist=False)
354
+ operand_references = relationship("OperandReference", back_populates="item")
355
+ context_compositions = relationship("ContextComposition", back_populates="item")
356
+ subcategory_items = relationship("SubCategoryItem", foreign_keys="SubCategoryItem.itemid", back_populates="item")
357
+ compound_item_contexts = relationship("CompoundItemContext", back_populates="item")
358
+
359
+
360
+ class ItemCategory(Base):
361
+ __tablename__ = "ItemCategory"
362
+
363
+ itemid = Column("ItemID", Integer, ForeignKey("Item.ItemID"), primary_key=True)
364
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"), primary_key=True)
365
+ categoryid = Column("CategoryID", Integer, ForeignKey("Category.CategoryID"))
366
+ code = Column("Code", String(20))
367
+ isdefaultitem = Column("IsDefaultItem", Boolean)
368
+ signature = Column("Signature", String(255))
369
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
370
+ rowguid = Column("RowGUID", String(36))
371
+
372
+ # Relationships
373
+ item = relationship("Item", back_populates="item_categories")
374
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
375
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
376
+ category = relationship("Category", foreign_keys=[categoryid])
377
+
378
+ @classmethod
379
+ def get_items(cls, session, items, release_id=None):
380
+ """
381
+ Get ItemCategory records for a list of item signatures.
382
+
383
+ Args:
384
+ session: SQLAlchemy session
385
+ items: List of item signatures to look up
386
+ release_id: Release ID to filter by (optional)
387
+
388
+ Returns:
389
+ DataFrame with ItemCategory data for the requested items
390
+ """
391
+ import pandas as pd
392
+ from sqlalchemy import or_
393
+
394
+ query = session.query(cls.signature.label('Signature'),
395
+ cls.code.label('Code'),
396
+ cls.categoryid.label('CategoryID'))
397
+
398
+ # Filter by signatures
399
+ if items:
400
+ query = query.filter(cls.signature.in_(items))
401
+
402
+ # Filter by release
403
+ if release_id is not None:
404
+ query = query.filter(
405
+ and_(
406
+ cls.startreleaseid <= release_id,
407
+ or_(cls.endreleaseid > release_id, cls.endreleaseid.is_(None))
408
+ )
409
+ )
410
+ else:
411
+ # Get current/active items (no end release)
412
+ query = query.filter(cls.endreleaseid.is_(None))
413
+
414
+ # Execute query and convert to DataFrame
415
+ result = query.all()
416
+ if result:
417
+ return pd.DataFrame([{
418
+ 'Signature': row.Signature,
419
+ 'Code': row.Code,
420
+ 'CategoryID': row.CategoryID
421
+ } for row in result])
422
+ else:
423
+ return pd.DataFrame(columns=['Signature', 'Code', 'CategoryID'])
424
+
425
+ class KeyComposition(Base):
426
+ __tablename__ = "KeyComposition"
427
+
428
+ keyid = Column("KeyID", Integer, ForeignKey("CompoundKey.KeyID"), primary_key=True)
429
+ variablevid = Column("VariableVID", Integer, ForeignKey("VariableVersion.VariableVID"), primary_key=True)
430
+ rowguid = Column("RowGUID", String(36))
431
+
432
+ # Relationships
433
+ compound_key = relationship("CompoundKey", back_populates="key_compositions")
434
+ variable_version = relationship("VariableVersion", back_populates="key_compositions")
435
+
436
+ class KeyHeaderMapping(Base):
437
+ __tablename__ = "KeyHeaderMapping"
438
+
439
+ associationid = Column("AssociationID", Integer, ForeignKey("TableAssociation.AssociationID"), primary_key=True)
440
+ foreignkeyheaderid = Column("ForeignKeyHeaderID", Integer, ForeignKey("Header.HeaderID"), primary_key=True)
441
+ primarykeyheaderid = Column("PrimaryKeyHeaderID", Integer, ForeignKey("Header.HeaderID"))
442
+ rowguid = Column("RowGUID", String(36))
443
+
444
+ # Relationships
445
+ table_association = relationship("TableAssociation", foreign_keys=[associationid])
446
+ foreign_key_header = relationship("Header", foreign_keys=[foreignkeyheaderid])
447
+ primary_key_header = relationship("Header", foreign_keys=[primarykeyheaderid])
448
+
449
+ class Language(Base):
450
+ __tablename__ = "Language"
451
+
452
+ languagecode = Column("LanguageCode", Integer, primary_key=True)
453
+ name = Column("Name", String(20))
454
+
455
+ # Relationships
456
+ translations = relationship("Translation", back_populates="language")
457
+
458
+ class ModelViolations(Base):
459
+ __tablename__ = "ModelViolations"
460
+
461
+ id = Column(Integer, primary_key=True, autoincrement=True)
462
+ violationcode = Column("ViolationCode", String(10))
463
+ violation = Column("Violation", String(255))
464
+ isblocking = Column("isBlocking", Boolean)
465
+ tablevid = Column("TableVID", Integer)
466
+ oldtablevid = Column("OldTableVID", Integer)
467
+ tablecode = Column("TableCode", String(40))
468
+ headerid = Column("HeaderID", Integer)
469
+ headercode = Column("HeaderCode", String(20))
470
+ headervid = Column("HeaderVID", Integer)
471
+ oldheadervid = Column("OldHeaderVID", Integer)
472
+ keyheader = Column("KeyHeader", Boolean)
473
+ headerdirection = Column("HeaderDirection", String(1))
474
+ headerpropertyid = Column("HeaderPropertyID", Integer)
475
+ headerpropertycode = Column("HeaderPropertyCode", String(20))
476
+ headersubcategoryid = Column("HeaderSubcategoryID", Integer)
477
+ headersubcategoryname = Column("HeaderSubcategoryName", String(60))
478
+ headercontextid = Column("HeaderContextID", Integer)
479
+ categoryid = Column("CategoryID", Integer)
480
+ categorycode = Column("CategoryCode", String(30))
481
+ itemid = Column("ItemID", Integer)
482
+ itemcode = Column("ItemCode", String(30))
483
+ cellid = Column("CellID", Integer)
484
+ cellcode = Column("CellCode", String(50))
485
+ cell2id = Column("Cell2ID", Integer)
486
+ cell2code = Column("Cell2Code", String(50))
487
+ vvendreleaseid = Column("VVEndReleaseID", Integer)
488
+ newaspect = Column("NewAspect", String(80))
489
+
490
+ class Module(Base):
491
+ __tablename__ = "Module"
492
+
493
+ moduleid = Column("ModuleID", Integer, primary_key=True)
494
+ frameworkid = Column("FrameworkID", Integer, ForeignKey("Framework.FrameworkID"))
495
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
496
+
497
+ # Relationships
498
+ framework = relationship("Framework", back_populates="modules")
499
+ concept = relationship("Concept", foreign_keys=[rowguid])
500
+ module_versions = relationship("ModuleVersion", back_populates="module")
501
+ variable_calculations = relationship("VariableCalculation", back_populates="module")
502
+
503
+ class ModuleParameters(Base):
504
+ __tablename__ = "ModuleParameters"
505
+
506
+ modulevid = Column("ModuleVID", Integer, ForeignKey("ModuleVersion.ModuleVID"), primary_key=True)
507
+ variablevid = Column("VariableVID", Integer, ForeignKey("VariableVersion.VariableVID"), primary_key=True)
508
+ rowguid = Column("RowGUID", String(36))
509
+
510
+ # Relationships
511
+ module_version = relationship("ModuleVersion", back_populates="module_parameters")
512
+ variable_version = relationship("VariableVersion", back_populates="module_parameters")
513
+
514
+ class ModuleVersion(Base):
515
+ __tablename__ = "ModuleVersion"
516
+
517
+ modulevid = Column("ModuleVID", Integer, primary_key=True)
518
+ moduleid = Column("ModuleID", Integer, ForeignKey("Module.ModuleID"))
519
+ globalkeyid = Column("GlobalKeyID", Integer, ForeignKey("CompoundKey.KeyID"))
520
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
521
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
522
+ code = Column("Code", String(30))
523
+ name = Column("Name", String(100))
524
+ description = Column("Description", String(255))
525
+ versionnumber = Column("VersionNumber", String(20))
526
+ fromreferencedate = Column("FromReferenceDate", Date)
527
+ toreferencedate = Column("ToReferenceDate", Date)
528
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
529
+
530
+ # Relationships
531
+ module = relationship("Module", back_populates="module_versions")
532
+ global_key = relationship("CompoundKey", foreign_keys=[globalkeyid])
533
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
534
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
535
+ concept = relationship("Concept", foreign_keys=[rowguid])
536
+ module_version_compositions = relationship("ModuleVersionComposition", back_populates="module_version")
537
+ operation_scope_compositions = relationship("OperationScopeComposition", back_populates="module_version")
538
+ module_parameters = relationship("ModuleParameters", back_populates="module_version")
539
+
540
+ __table_args__ = (
541
+ UniqueConstraint('ModuleID', 'StartReleaseID'),
542
+ )
543
+
544
+ class ModuleVersionComposition(Base):
545
+ __tablename__ = "ModuleVersionComposition"
546
+
547
+ modulevid = Column("ModuleVID", Integer, ForeignKey("ModuleVersion.ModuleVID"), primary_key=True)
548
+ tableid = Column("TableID", Integer, ForeignKey("Table.TableID"), primary_key=True)
549
+ tablevid = Column("TableVID", Integer, ForeignKey("TableVersion.TableVID"))
550
+ order = Column("Order", Integer)
551
+ rowguid = Column("RowGUID", String(36))
552
+
553
+ # Relationships
554
+ module_version = relationship("ModuleVersion", back_populates="module_version_compositions")
555
+ table = relationship("Table", back_populates="module_version_compositions")
556
+ table_version = relationship("TableVersion", back_populates="module_version_compositions")
557
+
558
+ class OperandReference(Base):
559
+ __tablename__ = "OperandReference"
560
+
561
+ operandreferenceid = Column("OperandReferenceID", Integer, primary_key=True)
562
+ nodeid = Column("NodeID", Integer, ForeignKey("OperationNode.NodeID"))
563
+ x = Column("x", Integer)
564
+ y = Column("y", Integer)
565
+ z = Column("z", Integer)
566
+ operandreference = Column("OperandReference", String(255))
567
+ itemid = Column("ItemID", Integer, ForeignKey("Item.ItemID"))
568
+ propertyid = Column("PropertyID", Integer, ForeignKey("Property.PropertyID"))
569
+ variableid = Column("VariableID", Integer, ForeignKey("Variable.VariableID"))
570
+ subcategoryid = Column("SubCategoryID", Integer, ForeignKey("SubCategory.SubCategoryID"))
571
+
572
+ # Relationships
573
+ operation_node = relationship("OperationNode", back_populates="operand_references")
574
+ item = relationship("Item", back_populates="operand_references")
575
+ property = relationship("Property", foreign_keys=[propertyid])
576
+ variable = relationship("Variable", back_populates="operand_references")
577
+ subcategory = relationship("SubCategory", foreign_keys=[subcategoryid])
578
+ operand_reference_locations = relationship("OperandReferenceLocation", back_populates="operand_reference")
579
+
580
+ class OperandReferenceLocation(Base):
581
+ __tablename__ = "OperandReferenceLocation"
582
+
583
+ operandreferenceid = Column("OperandReferenceID", Integer, ForeignKey("OperandReference.OperandReferenceID"), primary_key=True)
584
+ cellid = Column("CellID", Integer, ForeignKey("Cell.CellID"))
585
+ table = Column("Table", String(255))
586
+ row = Column("Row", String(255))
587
+ column = Column("Column", String(255))
588
+ sheet = Column("Sheet", String(255))
589
+
590
+ # Relationships
591
+ operand_reference = relationship("OperandReference", back_populates="operand_reference_locations")
592
+ cell = relationship("Cell", back_populates="operand_reference_locations")
593
+
594
+ class Operation(Base):
595
+ __tablename__ = "Operation"
596
+
597
+ operationid = Column("OperationID", Integer, primary_key=True)
598
+ code = Column("Code", String(20))
599
+ type = Column("Type", String(20))
600
+ source = Column("Source", String(20))
601
+ groupoperid = Column("GroupOperID", Integer, ForeignKey("Operation.OperationID"))
602
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
603
+
604
+ # Relationships
605
+ group_operation = relationship("Operation", remote_side=[operationid], back_populates="grouped_operations")
606
+ grouped_operations = relationship("Operation", back_populates="group_operation")
607
+ concept = relationship("Concept", foreign_keys=[rowguid])
608
+ operation_versions = relationship("OperationVersion", back_populates="operation")
609
+
610
+ class OperationCodePrefix(Base):
611
+ __tablename__ = "OperationCodePrefix"
612
+
613
+ operationcodeprefixid = Column("OperationCodePrefixID", Integer, primary_key=True)
614
+ code = Column("Code", String(20), unique=True)
615
+ listname = Column("ListName", String(20))
616
+ frameworkid = Column("FrameworkID", Integer, ForeignKey("Framework.FrameworkID"))
617
+
618
+ # Relationships
619
+ framework = relationship("Framework", back_populates="operation_code_prefixes")
620
+
621
+ class OperationNode(Base):
622
+ __tablename__ = "OperationNode"
623
+
624
+ nodeid = Column("NodeID", Integer, primary_key=True)
625
+ operationvid = Column("OperationVID", Integer, ForeignKey("OperationVersion.OperationVID"))
626
+ parentnodeid = Column("ParentNodeID", Integer, ForeignKey("OperationNode.NodeID"))
627
+ operatorid = Column("OperatorID", Integer, ForeignKey("Operator.OperatorID"))
628
+ argumentid = Column("ArgumentID", Integer, ForeignKey("OperatorArgument.ArgumentID"))
629
+ absolutetolerance = Column("AbsoluteTolerance", String)
630
+ relativetolerance = Column("RelativeTolerance", String)
631
+ fallbackvalue = Column("FallbackValue", String(50))
632
+ useintervalarithmetics = Column("UseIntervalArithmetics", Boolean)
633
+ operandtype = Column("OperandType", String(20))
634
+ isleaf = Column("IsLeaf", Boolean)
635
+ scalar = Column("Scalar", Text)
636
+
637
+ # Relationships
638
+ operation_version = relationship("OperationVersion", back_populates="operation_nodes")
639
+ parent = relationship("OperationNode", remote_side=[nodeid], back_populates="children")
640
+ children = relationship("OperationNode", back_populates="parent")
641
+ operator = relationship("Operator", foreign_keys=[operatorid])
642
+ operator_argument = relationship("OperatorArgument", foreign_keys=[argumentid])
643
+ operand_references = relationship("OperandReference", back_populates="operation_node")
644
+
645
+ class OperationScope(Base):
646
+ __tablename__ = "OperationScope"
647
+
648
+ operationscopeid = Column("OperationScopeID", Integer, primary_key=True)
649
+ operationvid = Column("OperationVID", Integer, ForeignKey("OperationVersion.OperationVID"))
650
+ isactive = Column("IsActive", Boolean)
651
+ severity = Column("Severity", String(20))
652
+ fromsubmissiondate = Column("FromSubmissionDate", Date)
653
+ rowguid = Column("RowGUID", String(36))
654
+
655
+ # Relationships
656
+ operation_version = relationship("OperationVersion", back_populates="operation_scopes")
657
+ operation_scope_compositions = relationship("OperationScopeComposition", back_populates="operation_scope")
658
+
659
+ class OperationScopeComposition(Base):
660
+ __tablename__ = "OperationScopeComposition"
661
+
662
+ operationscopeid = Column("OperationScopeID", Integer, ForeignKey("OperationScope.OperationScopeID"), primary_key=True)
663
+ modulevid = Column("ModuleVID", Integer, ForeignKey("ModuleVersion.ModuleVID"), primary_key=True)
664
+ rowguid = Column("RowGUID", String(36))
665
+
666
+ # Relationships
667
+ operation_scope = relationship("OperationScope", back_populates="operation_scope_compositions")
668
+ module_version = relationship("ModuleVersion", back_populates="operation_scope_compositions")
669
+
670
+ class OperationVersion(Base):
671
+ __tablename__ = "OperationVersion"
672
+
673
+ operationvid = Column("OperationVID", Integer, primary_key=True)
674
+ operationid = Column("OperationID", Integer, ForeignKey("Operation.OperationID"))
675
+ preconditionoperationvid = Column("PreconditionOperationVID", Integer, ForeignKey("OperationVersion.OperationVID"))
676
+ severityoperationvid = Column("SeverityOperationVID", Integer, ForeignKey("OperationVersion.OperationVID"))
677
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
678
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
679
+ expression = Column("Expression", Text)
680
+ description = Column("Description", String(1000))
681
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
682
+ endorsement = Column("Endorsement", String(25))
683
+ isvariantapproved = Column("IsVariantApproved", Boolean)
684
+
685
+ # Relationships
686
+ operation = relationship("Operation", back_populates="operation_versions")
687
+ precondition_operation = relationship("OperationVersion",
688
+ remote_side=[operationvid],
689
+ foreign_keys=[preconditionoperationvid],
690
+ back_populates="precondition_dependent_operations")
691
+ severity_operation = relationship("OperationVersion",
692
+ remote_side=[operationvid],
693
+ foreign_keys=[severityoperationvid],
694
+ back_populates="severity_dependent_operations")
695
+ precondition_dependent_operations = relationship("OperationVersion",
696
+ foreign_keys=[preconditionoperationvid],
697
+ back_populates="precondition_operation")
698
+ severity_dependent_operations = relationship("OperationVersion",
699
+ foreign_keys=[severityoperationvid],
700
+ back_populates="severity_operation")
701
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
702
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
703
+ concept = relationship("Concept", foreign_keys=[rowguid])
704
+ operation_nodes = relationship("OperationNode", back_populates="operation_version")
705
+ operation_scopes = relationship("OperationScope", back_populates="operation_version")
706
+ operation_version_data = relationship("OperationVersionData", back_populates="operation_version", uselist=False)
707
+ variable_calculations = relationship("VariableCalculation", back_populates="operation_version")
708
+
709
+ __table_args__ = (
710
+ UniqueConstraint('OperationID', 'StartReleaseID'),
711
+ )
712
+
713
+ class OperationVersionData(Base):
714
+ __tablename__ = "OperationVersionData"
715
+
716
+ operationvid = Column("OperationVID", Integer, ForeignKey("OperationVersion.OperationVID"), primary_key=True)
717
+ error = Column("Error", String(2000))
718
+ errorcode = Column("ErrorCode", String(50))
719
+ isapplying = Column("IsApplying", Boolean)
720
+ proposingstatus = Column("ProposingStatus", String(50))
721
+
722
+ # Relationships
723
+ operation_version = relationship("OperationVersion", back_populates="operation_version_data")
724
+
725
+ class Operator(Base):
726
+ __tablename__ = "Operator"
727
+
728
+ operatorid = Column("OperatorID", Integer, primary_key=True)
729
+ name = Column("Name", String(50))
730
+ symbol = Column("Symbol", String(20))
731
+ type = Column("Type", String(20))
732
+
733
+ # Relationships
734
+ operator_arguments = relationship("OperatorArgument", back_populates="operator")
735
+ operation_nodes = relationship("OperationNode", back_populates="operator")
736
+ comparison_subcategory_items = relationship("SubCategoryItem",
737
+ foreign_keys="SubCategoryItem.comparisonoperatorid",
738
+ back_populates="comparison_operator")
739
+ arithmetic_subcategory_items = relationship("SubCategoryItem",
740
+ foreign_keys="SubCategoryItem.arithmeticoperatorid",
741
+ back_populates="arithmetic_operator")
742
+
743
+ class OperatorArgument(Base):
744
+ __tablename__ = "OperatorArgument"
745
+
746
+ argumentid = Column("ArgumentID", Integer, primary_key=True)
747
+ operatorid = Column("OperatorID", Integer, ForeignKey("Operator.OperatorID"))
748
+ order = Column("Order", SmallInteger)
749
+ ismandatory = Column("IsMandatory", Boolean)
750
+ name = Column("Name", String(50))
751
+
752
+ # Relationships
753
+ operator = relationship("Operator", back_populates="operator_arguments")
754
+ operation_nodes = relationship("OperationNode", back_populates="operator_argument")
755
+
756
+ class Organisation(Base):
757
+ __tablename__ = "Organisation"
758
+
759
+ orgid = Column("OrgID", Integer, primary_key=True)
760
+ name = Column("Name", String(200), unique=True)
761
+ acronym = Column("Acronym", String(20))
762
+ idprefix = Column("IDPrefix", Integer, unique=True)
763
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
764
+
765
+ # Relationships
766
+ concept = relationship("Concept", foreign_keys=[rowguid])
767
+ concepts_owned = relationship("Concept", foreign_keys="Concept.ownerid", back_populates="owner")
768
+ documents = relationship("Document", back_populates="organisation")
769
+ users = relationship("User", back_populates="organisation")
770
+ translations = relationship("Translation", back_populates="translator")
771
+
772
+ class Property(Base):
773
+ __tablename__ = "Property"
774
+
775
+ propertyid = Column("PropertyID", Integer, ForeignKey("Item.ItemID"), primary_key=True)
776
+ iscomposite = Column("IsComposite", Boolean)
777
+ ismetric = Column("IsMetric", Boolean)
778
+ datatypeid = Column("DataTypeID", Integer, ForeignKey("DataType.DataTypeID"))
779
+ valuelength = Column("ValueLength", Integer)
780
+ periodtype = Column("PeriodType", String(20))
781
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
782
+
783
+ # Relationships
784
+ item = relationship("Item", back_populates="property")
785
+ datatype = relationship("DataType", back_populates="properties")
786
+ concept = relationship("Concept", foreign_keys=[rowguid])
787
+ property_categories = relationship("PropertyCategory", back_populates="property")
788
+ context_compositions = relationship("ContextComposition", back_populates="property")
789
+ variable_versions = relationship("VariableVersion", back_populates="property")
790
+ header_versions = relationship("HeaderVersion", back_populates="property")
791
+ table_versions = relationship("TableVersion", back_populates="property")
792
+
793
+ class PropertyCategory(Base):
794
+ __tablename__ = "PropertyCategory"
795
+
796
+ propertyid = Column("PropertyID", Integer, ForeignKey("Property.PropertyID"), primary_key=True)
797
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"), primary_key=True)
798
+ categoryid = Column("CategoryID", Integer, ForeignKey("Category.CategoryID"))
799
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
800
+ rowguid = Column("RowGUID", String(36))
801
+
802
+ # Relationships
803
+ property = relationship("Property", back_populates="property_categories")
804
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
805
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
806
+ category = relationship("Category", back_populates="property_categories")
807
+
808
+ class Reference(Base):
809
+ __tablename__ = "Reference"
810
+
811
+ subdivisionid = Column("SubdivisionID", Integer, ForeignKey("Subdivision.SubdivisionID"), primary_key=True)
812
+ conceptguid = Column("ConceptGUID", String(36), ForeignKey("Concept.ConceptGUID"), primary_key=True)
813
+ rowguid = Column("RowGUID", String(36))
814
+
815
+ # Relationships
816
+ subdivision = relationship("Subdivision", back_populates="references")
817
+ concept = relationship("Concept", foreign_keys=[conceptguid])
818
+
819
+ class RelatedConcept(Base):
820
+ __tablename__ = "RelatedConcept"
821
+
822
+ conceptguid = Column("ConceptGUID", String(36), ForeignKey("Concept.ConceptGUID"), primary_key=True)
823
+ conceptrelationid = Column("ConceptRelationID", Integer, ForeignKey("ConceptRelation.ConceptRelationID"), primary_key=True)
824
+ isrelatedconcept = Column("IsRelatedConcept", Boolean)
825
+ rowguid = Column("RowGUID", String(36))
826
+
827
+ # Relationships
828
+ concept = relationship("Concept", back_populates="related_concepts")
829
+ concept_relation = relationship("ConceptRelation", back_populates="related_concepts")
830
+
831
+ class Release(Base):
832
+ __tablename__ = "Release"
833
+
834
+ releaseid = Column("ReleaseID", Integer, primary_key=True)
835
+ code = Column("Code", String(20))
836
+ date = Column("Date", Date)
837
+ description = Column("Description", String(255))
838
+ status = Column("Status", String(50))
839
+ iscurrent = Column("IsCurrent", Boolean)
840
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
841
+ latestvariablegentime = Column("LatestVariableGenTime", DateTime)
842
+ name = Column("Name", String(50))
843
+
844
+ # Relationships
845
+ concept = relationship("Concept", foreign_keys=[rowguid])
846
+ changelogs = relationship("Changelog", back_populates="release")
847
+ variable_generations = relationship("VariableGeneration", back_populates="release")
848
+
849
+ class Role(Base):
850
+ __tablename__ = "Role"
851
+
852
+ roleid = Column("RoleID", Integer, primary_key=True)
853
+ name = Column("Name", String(50))
854
+
855
+ # Relationships
856
+ user_roles = relationship("UserRole", back_populates="role")
857
+
858
+ class SubCategoryItem(Base):
859
+ __tablename__ = "SubCategoryItem"
860
+
861
+ itemid = Column("ItemID", Integer, ForeignKey("Item.ItemID"), primary_key=True)
862
+ subcategoryvid = Column("SubCategoryVID", Integer, ForeignKey("SubCategoryVersion.SubCategoryVID"), primary_key=True)
863
+ order = Column("Order", Integer)
864
+ label = Column("Label", String(200))
865
+ parentitemid = Column("ParentItemID", Integer, ForeignKey("Item.ItemID"))
866
+ comparisonoperatorid = Column("ComparisonOperatorID", Integer, ForeignKey("Operator.OperatorID"))
867
+ arithmeticoperatorid = Column("ArithmeticOperatorID", Integer, ForeignKey("Operator.OperatorID"))
868
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
869
+
870
+ # Relationships - specify foreign_keys to resolve ambiguity
871
+ item = relationship("Item", foreign_keys=[itemid], back_populates="subcategory_items")
872
+ subcategory_version = relationship("SubCategoryVersion", back_populates="subcategory_items")
873
+ parent_item = relationship("Item", foreign_keys=[parentitemid])
874
+ comparison_operator = relationship("Operator", foreign_keys=[comparisonoperatorid], back_populates="comparison_subcategory_items")
875
+ arithmetic_operator = relationship("Operator", foreign_keys=[arithmeticoperatorid], back_populates="arithmetic_subcategory_items")
876
+ concept = relationship("Concept", foreign_keys=[rowguid])
877
+
878
+
879
+ class SubCategoryVersion(Base):
880
+ __tablename__ = "SubCategoryVersion"
881
+
882
+ subcategoryvid = Column("SubCategoryVID", Integer, primary_key=True)
883
+ subcategoryid = Column("SubCategoryID", Integer, ForeignKey("SubCategory.SubCategoryID"))
884
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
885
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
886
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
887
+
888
+ # Relationships
889
+ subcategory = relationship("SubCategory", back_populates="subcategory_versions")
890
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
891
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
892
+ concept = relationship("Concept", foreign_keys=[rowguid])
893
+ subcategory_items = relationship("SubCategoryItem", back_populates="subcategory_version")
894
+ header_versions = relationship("HeaderVersion", back_populates="subcategory_version")
895
+ variable_versions = relationship("VariableVersion", back_populates="subcategory_version")
896
+
897
+ __table_args__ = (
898
+ UniqueConstraint('SubCategoryID', 'StartReleaseID'),
899
+ )
900
+
901
+ class Subdivision(Base):
902
+ __tablename__ = "Subdivision"
903
+
904
+ subdivisionid = Column("SubdivisionID", Integer, primary_key=True)
905
+ documentvid = Column("DocumentVID", Integer, ForeignKey("DocumentVersion.DocumentVID"))
906
+ subdivisiontypeid = Column("SubdivisionTypeID", Integer, ForeignKey("SubdivisionType.SubdivisionTypeID"))
907
+ number = Column("Number", String(20))
908
+ parentsubdivisionid = Column("ParentSubdivisionID", Integer, ForeignKey("Subdivision.SubdivisionID"))
909
+ structurepath = Column("StructurePath", String(255))
910
+ textexcerpt = Column("TextExcerpt", Text)
911
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
912
+
913
+ # Relationships
914
+ document_version = relationship("DocumentVersion", back_populates="subdivisions")
915
+ subdivision_type = relationship("SubdivisionType", back_populates="subdivisions")
916
+ parent_subdivision = relationship("Subdivision", remote_side=[subdivisionid], back_populates="child_subdivisions")
917
+ child_subdivisions = relationship("Subdivision", back_populates="parent_subdivision")
918
+ concept = relationship("Concept", foreign_keys=[rowguid])
919
+ references = relationship("Reference", back_populates="subdivision")
920
+
921
+ class SubdivisionType(Base):
922
+ __tablename__ = "SubdivisionType"
923
+
924
+ subdivisiontypeid = Column("SubdivisionTypeID", Integer, primary_key=True)
925
+ name = Column("Name", String(50))
926
+ description = Column("Description", String(255))
927
+
928
+ # Relationships
929
+ subdivisions = relationship("Subdivision", back_populates="subdivision_type")
930
+
931
+ class SupercategoryComposition(Base):
932
+ __tablename__ = "SuperCategoryComposition"
933
+
934
+ supercategoryid = Column("SuperCategoryID", Integer, ForeignKey("Category.CategoryID"), primary_key=True)
935
+ categoryid = Column("CategoryID", Integer, ForeignKey("Category.CategoryID"), primary_key=True)
936
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
937
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
938
+ rowguid = Column("RowGUID", String(36))
939
+
940
+ # Relationships
941
+ supercategory = relationship("Category", foreign_keys=[supercategoryid], back_populates="supercategory_compositions")
942
+ category = relationship("Category", foreign_keys=[categoryid], back_populates="category_compositions")
943
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
944
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
945
+
946
+ class Table(Base):
947
+ __tablename__ = "Table"
948
+
949
+ tableid = Column("TableID", Integer, primary_key=True)
950
+ isabstract = Column("IsAbstract", Boolean)
951
+ hasopencolumns = Column("HasOpenColumns", Boolean)
952
+ hasopenrows = Column("HasOpenRows", Boolean)
953
+ hasopensheets = Column("HasOpenSheets", Boolean)
954
+ isnormalised = Column("IsNormalised", Boolean)
955
+ isflat = Column("IsFlat", Boolean)
956
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
957
+
958
+ # Relationships - specify foreign_keys to resolve ambiguity
959
+ concept = relationship("Concept", foreign_keys=[rowguid])
960
+ headers = relationship("Header", back_populates="table")
961
+ cells = relationship("Cell", back_populates="table")
962
+ table_versions = relationship("TableVersion", foreign_keys="TableVersion.tableid", back_populates="table")
963
+ abstract_table_versions = relationship("TableVersion", foreign_keys="TableVersion.abstracttableid", back_populates="abstract_table")
964
+ table_group_compositions = relationship("TableGroupComposition", back_populates="table")
965
+ module_version_compositions = relationship("ModuleVersionComposition", back_populates="table")
966
+
967
+ class TableAssociation(Base):
968
+ __tablename__ = "TableAssociation"
969
+
970
+ associationid = Column("AssociationID", Integer, primary_key=True)
971
+ childtablevid = Column("ChildTableVID", Integer, ForeignKey("TableVersion.TableVID"))
972
+ parenttablevid = Column("ParentTableVID", Integer, ForeignKey("TableVersion.TableVID"))
973
+ name = Column("Name", String(50))
974
+ description = Column("Description", String(255))
975
+ isidentifying = Column("IsIdentifying", Boolean)
976
+ issubtype = Column("IsSubtype", Boolean)
977
+ subtypediscriminator = Column("SubtypeDiscriminator", Integer, ForeignKey("Header.HeaderID"))
978
+ parentcardinalityandoptionality = Column("ParentCardinalityAndOptionality", String(3))
979
+ childcardinalityandoptionality = Column("ChildCardinalityAndOptionality", String(3))
980
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
981
+
982
+ # Relationships
983
+ child_table_version = relationship("TableVersion", foreign_keys=[childtablevid], back_populates="table_associations_as_child")
984
+ parent_table_version = relationship("TableVersion", foreign_keys=[parenttablevid], back_populates="table_associations_as_parent")
985
+ subtype_discriminator = relationship("Header", foreign_keys=[subtypediscriminator])
986
+ concept = relationship("Concept", foreign_keys=[rowguid])
987
+ key_header_mappings = relationship("KeyHeaderMapping", back_populates="table_association")
988
+
989
+ class TableGroup(Base):
990
+ __tablename__ = "TableGroup"
991
+
992
+ tablegroupid = Column("TableGroupID", Integer, primary_key=True)
993
+ code = Column("Code", String(255))
994
+ name = Column("Name", String(255))
995
+ description = Column("Description", String(2000))
996
+ type = Column("Type", String(20))
997
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
998
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
999
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1000
+ parenttablegroupid = Column("ParentTableGroupID", Integer, ForeignKey("TableGroup.TableGroupID"))
1001
+
1002
+ # Relationships
1003
+ concept = relationship("Concept", foreign_keys=[rowguid])
1004
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
1005
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
1006
+ parent_table_group = relationship("TableGroup", remote_side=[tablegroupid], back_populates="child_table_groups")
1007
+ child_table_groups = relationship("TableGroup", back_populates="parent_table_group")
1008
+ table_group_compositions = relationship("TableGroupComposition", back_populates="table_group")
1009
+
1010
+ class TableGroupComposition(Base):
1011
+ __tablename__ = "TableGroupComposition"
1012
+
1013
+ tablegroupid = Column("TableGroupID", Integer, ForeignKey("TableGroup.TableGroupID"), primary_key=True)
1014
+ tableid = Column("TableID", Integer, ForeignKey("Table.TableID"), primary_key=True)
1015
+ order = Column("Order", Integer)
1016
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1017
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1018
+ rowguid = Column("RowGUID", String(36))
1019
+
1020
+ # Relationships
1021
+ table_group = relationship("TableGroup", back_populates="table_group_compositions")
1022
+ table = relationship("Table", back_populates="table_group_compositions")
1023
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
1024
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
1025
+ class TableVersion(Base):
1026
+ __tablename__ = "TableVersion"
1027
+
1028
+ tablevid = Column("TableVID", Integer, primary_key=True)
1029
+ code = Column("Code", String(30))
1030
+ name = Column("Name", String(255))
1031
+ description = Column("Description", String(500))
1032
+ tableid = Column("TableID", Integer, ForeignKey("Table.TableID"))
1033
+ abstracttableid = Column("AbstractTableID", Integer, ForeignKey("Table.TableID"))
1034
+ keyid = Column("KeyID", Integer, ForeignKey("CompoundKey.KeyID"))
1035
+ propertyid = Column("PropertyID", Integer, ForeignKey("Property.PropertyID"))
1036
+ contextid = Column("ContextID", Integer, ForeignKey("Context.ContextID"))
1037
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1038
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1039
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
1040
+
1041
+ # Relationships - specify foreign_keys to resolve ambiguity
1042
+ table = relationship("Table", foreign_keys=[tableid], back_populates="table_versions")
1043
+ abstract_table = relationship("Table", foreign_keys=[abstracttableid], back_populates="abstract_table_versions")
1044
+ key = relationship("CompoundKey", foreign_keys=[keyid])
1045
+ property = relationship("Property", foreign_keys=[propertyid])
1046
+ context = relationship("Context", foreign_keys=[contextid])
1047
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
1048
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
1049
+ concept = relationship("Concept", foreign_keys=[rowguid])
1050
+ table_version_cells = relationship("TableVersionCell", back_populates="table_version")
1051
+ table_version_headers = relationship("TableVersionHeader", back_populates="table_version")
1052
+ table_associations_as_child = relationship("TableAssociation", foreign_keys="TableAssociation.childtablevid", back_populates="child_table_version")
1053
+ table_associations_as_parent = relationship("TableAssociation", foreign_keys="TableAssociation.parenttablevid", back_populates="parent_table_version")
1054
+ module_version_compositions = relationship("ModuleVersionComposition", back_populates="table_version")
1055
+
1056
+ __table_args__ = (
1057
+ UniqueConstraint('TableID', 'StartReleaseID'),
1058
+ )
1059
+
1060
+ class TableVersionCell(Base):
1061
+ __tablename__ = "TableVersionCell"
1062
+
1063
+ tablevid = Column("TableVID", Integer, ForeignKey("TableVersion.TableVID"), primary_key=True)
1064
+ cellid = Column("CellID", Integer, ForeignKey("Cell.CellID"), primary_key=True)
1065
+ cellcode = Column("CellCode", String(100))
1066
+ isnullable = Column("IsNullable", Boolean)
1067
+ isexcluded = Column("IsExcluded", Boolean)
1068
+ isvoid = Column("IsVoid", Boolean)
1069
+ sign = Column("Sign", String(8))
1070
+ variablevid = Column("VariableVID", Integer, ForeignKey("VariableVersion.VariableVID"))
1071
+ rowguid = Column("RowGUID", String(36))
1072
+
1073
+ # Relationships
1074
+ table_version = relationship("TableVersion", back_populates="table_version_cells")
1075
+ cell = relationship("Cell", back_populates="table_version_cells")
1076
+ variable_version = relationship("VariableVersion", back_populates="table_version_cells")
1077
+
1078
+ class TableVersionHeader(Base):
1079
+ __tablename__ = "TableVersionHeader"
1080
+
1081
+ tablevid = Column("TableVID", Integer, ForeignKey("TableVersion.TableVID"), primary_key=True)
1082
+ headerid = Column("HeaderID", Integer, ForeignKey("Header.HeaderID"), primary_key=True)
1083
+ headervid = Column("HeaderVID", Integer, ForeignKey("HeaderVersion.HeaderVID"))
1084
+ parentheaderid = Column("ParentHeaderID", Integer, ForeignKey("Header.HeaderID"))
1085
+ parentfirst = Column("ParentFirst", Boolean)
1086
+ order = Column("Order", Integer)
1087
+ isabstract = Column("IsAbstract", Boolean)
1088
+ isunique = Column("IsUnique", Boolean)
1089
+ rowguid = Column("RowGUID", String(36))
1090
+
1091
+ # Relationships
1092
+ table_version = relationship("TableVersion", back_populates="table_version_headers")
1093
+ header = relationship("Header", foreign_keys=[headerid])
1094
+ header_version = relationship("HeaderVersion", foreign_keys=[headervid])
1095
+ parent_header = relationship("Header", foreign_keys=[parentheaderid])
1096
+
1097
+ class Translation(Base):
1098
+ __tablename__ = "Translation"
1099
+
1100
+ conceptguid = Column("ConceptGUID", String(36), ForeignKey("Concept.ConceptGUID"), primary_key=True)
1101
+ attributeid = Column("AttributeID", Integer, ForeignKey("DPMAttribute.AttributeID"), primary_key=True)
1102
+ translatorid = Column("TranslatorID", Integer, ForeignKey("Organisation.OrgID"), primary_key=True)
1103
+ languagecode = Column("LanguageCode", Integer, ForeignKey("Language.LanguageCode"), primary_key=True)
1104
+ translation = Column("Translation", Text)
1105
+ rowguid = Column("RowGUID", String(36))
1106
+
1107
+ # Relationships
1108
+ concept = relationship("Concept", foreign_keys=[conceptguid])
1109
+ dpm_attribute = relationship("DpmAttribute", back_populates="translations")
1110
+ translator = relationship("Organisation", foreign_keys=[translatorid], back_populates="translations")
1111
+ language = relationship("Language", back_populates="translations")
1112
+
1113
+ class User(Base):
1114
+ __tablename__ = "User"
1115
+
1116
+ userid = Column("UserID", Integer, primary_key=True)
1117
+ orgid = Column("OrgID", Integer, ForeignKey("Organisation.OrgID"))
1118
+ name = Column("Name", String(50))
1119
+
1120
+ # Relationships
1121
+ organisation = relationship("Organisation", back_populates="users")
1122
+ user_roles = relationship("UserRole", back_populates="user")
1123
+ changelogs = relationship("Changelog", back_populates="user")
1124
+
1125
+ class UserRole(Base):
1126
+ __tablename__ = "UserRole"
1127
+
1128
+ userid = Column("UserID", Integer, ForeignKey("User.UserID"), primary_key=True)
1129
+ roleid = Column("RoleID", Integer, ForeignKey("Role.RoleID"), primary_key=True)
1130
+
1131
+ # Relationships
1132
+ user = relationship("User", back_populates="user_roles")
1133
+ role = relationship("Role", back_populates="user_roles")
1134
+
1135
+ class Variable(Base):
1136
+ __tablename__ = "Variable"
1137
+
1138
+ variableid = Column("VariableID", Integer, primary_key=True)
1139
+ type = Column("Type", String(20))
1140
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
1141
+
1142
+ # Relationships
1143
+ concept = relationship("Concept", foreign_keys=[rowguid])
1144
+ variable_versions = relationship("VariableVersion", back_populates="variable")
1145
+ variable_calculations = relationship("VariableCalculation", back_populates="variable")
1146
+ operand_references = relationship("OperandReference", back_populates="variable")
1147
+
1148
+ class VariableCalculation(Base):
1149
+ __tablename__ = "VariableCalculation"
1150
+
1151
+ moduleid = Column("ModuleID", Integer, ForeignKey("Module.ModuleID"), primary_key=True)
1152
+ variableid = Column("VariableID", Integer, ForeignKey("Variable.VariableID"), primary_key=True)
1153
+ operationvid = Column("OperationVID", Integer, ForeignKey("OperationVersion.OperationVID"), primary_key=True)
1154
+ fromreferencedate = Column("FromReferenceDate", Date)
1155
+ toreferencedate = Column("ToReferenceDate", Date)
1156
+ rowguid = Column("RowGUID", String(36))
1157
+
1158
+ # Relationships
1159
+ module = relationship("Module", back_populates="variable_calculations")
1160
+ variable = relationship("Variable", back_populates="variable_calculations")
1161
+ operation_version = relationship("OperationVersion", back_populates="variable_calculations")
1162
+
1163
+ class VariableGeneration(Base):
1164
+ __tablename__ = "VariableGeneration"
1165
+
1166
+ variablegenerationid = Column("VariableGenerationID", Integer, primary_key=True)
1167
+ startdate = Column("StartDate", DateTime)
1168
+ enddate = Column("EndDate", DateTime)
1169
+ status = Column("Status", String(50))
1170
+ releaseid = Column("ReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1171
+ error = Column("Error", String(4000))
1172
+
1173
+ # Relationships
1174
+ release = relationship("Release", back_populates="variable_generations")
1175
+
1176
+ class VariableVersion(Base):
1177
+ __tablename__ = "VariableVersion"
1178
+
1179
+ variablevid = Column("VariableVID", Integer, primary_key=True)
1180
+ variableid = Column("VariableID", Integer, ForeignKey("Variable.VariableID"))
1181
+ propertyid = Column("PropertyID", Integer, ForeignKey("Property.PropertyID"))
1182
+ subcategoryvid = Column("SubCategoryVID", Integer, ForeignKey("SubCategoryVersion.SubCategoryVID"))
1183
+ contextid = Column("ContextID", Integer, ForeignKey("Context.ContextID"))
1184
+ keyid = Column("KeyID", Integer, ForeignKey("CompoundKey.KeyID"))
1185
+ ismultivalued = Column("IsMultiValued", Boolean)
1186
+ code = Column("Code", String(20))
1187
+ name = Column("Name", String(50))
1188
+ startreleaseid = Column("StartReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1189
+ endreleaseid = Column("EndReleaseID", Integer, ForeignKey("Release.ReleaseID"))
1190
+ rowguid = Column("RowGUID", String(36), ForeignKey("Concept.ConceptGUID"))
1191
+
1192
+ # Relationships
1193
+ variable = relationship("Variable", back_populates="variable_versions")
1194
+ property = relationship("Property", back_populates="variable_versions")
1195
+ subcategory_version = relationship("SubCategoryVersion", back_populates="variable_versions")
1196
+ context = relationship("Context", back_populates="variable_versions")
1197
+ key = relationship("CompoundKey", foreign_keys=[keyid])
1198
+ start_release = relationship("Release", foreign_keys=[startreleaseid])
1199
+ end_release = relationship("Release", foreign_keys=[endreleaseid])
1200
+ concept = relationship("Concept", foreign_keys=[rowguid])
1201
+ key_compositions = relationship("KeyComposition", back_populates="variable_version")
1202
+ module_parameters = relationship("ModuleParameters", back_populates="variable_version")
1203
+ table_version_cells = relationship("TableVersionCell", back_populates="variable_version")
1204
+ header_versions = relationship("HeaderVersion", back_populates="key_variable_version")
1205
+
1206
+ __table_args__ = (
1207
+ UniqueConstraint('VariableID', 'StartReleaseID'),
1208
+ )
1209
+
1210
+ @classmethod
1211
+ def check_variable_exists(cls, session, variable_code, release_id=None):
1212
+ """
1213
+ Check if a variable exists in the database.
1214
+
1215
+ Args:
1216
+ session: SQLAlchemy session
1217
+ variable_code: Variable code to check
1218
+ release_id: Release ID to filter by (optional)
1219
+
1220
+ Returns:
1221
+ Boolean indicating if the variable exists
1222
+ """
1223
+ from sqlalchemy import or_
1224
+
1225
+ query = session.query(cls).filter(cls.code == variable_code)
1226
+
1227
+ # Filter by release
1228
+ if release_id is not None:
1229
+ query = query.filter(
1230
+ and_(
1231
+ cls.startreleaseid <= release_id,
1232
+ or_(cls.endreleaseid > release_id, cls.endreleaseid.is_(None))
1233
+ )
1234
+ )
1235
+ else:
1236
+ # Check current/active variables (no end release)
1237
+ query = query.filter(cls.endreleaseid.is_(None))
1238
+
1239
+ return query.first() is not None
1240
+
1241
+ # Utility functions (keep these from your original models)
1242
+ def filter_by_release(query, start_release, end_release, release_id):
1243
+ """
1244
+ Live Release: EndReleaseID is NULL
1245
+ Specific Release: StartReleaseID <= ? and (EndReleaseID > ? or EndReleaseID is NULL)
1246
+ """
1247
+ if release_id is None:
1248
+ return query.filter(and_(end_release.is_(None), True))
1249
+ return query.filter(and_(start_release <= release_id,
1250
+ or_(end_release > release_id,
1251
+ end_release.is_(None))))
1252
+
1253
+ def filter_by_date(query, start_date, end_date, date):
1254
+ date = datetime.strptime(date, '%Y-%m-%d')
1255
+ if date is None:
1256
+ return query.filter(and_(end_date.is_(None), True))
1257
+ return query.filter(and_(start_date <= date), or_(end_date > date, end_date.is_(None)))
1258
+
1259
+ def filter_elements(query, column, values):
1260
+ if len(values) == 1:
1261
+ if values[0] == '*':
1262
+ return query.filter(column.is_not(None))
1263
+ elif '-' in values[0]:
1264
+ limits = values[0].split('-')
1265
+ return query.filter(column.between(limits[0], limits[1]))
1266
+ else:
1267
+ return query.filter(column == values[0])
1268
+ range_control = any(['-' in x for x in values])
1269
+ if not range_control:
1270
+ return query.filter(column.in_(values))
1271
+ dynamic_filter = []
1272
+ for x in values:
1273
+ if '-' in x:
1274
+ limits = x.split('-')
1275
+ dynamic_filter.append(column.between(limits[0], limits[1]))
1276
+ else:
1277
+ dynamic_filter.append(column == x)
1278
+ return query.filter(or_((x for x in dynamic_filter)))
1279
+
1280
+ def _check_ranges_values_are_present(data: pd.DataFrame, data_column, values):
1281
+ if values is not None and '-' in values[0]:
1282
+ test = values[0].split('-')
1283
+ if test[0] not in list(data[data_column].values):
1284
+ data = pd.DataFrame(columns=data.columns)
1285
+ if test[1] not in list(data[data_column].values):
1286
+ data = pd.DataFrame(columns=data.columns)
1287
+ return data
1288
+
1289
+ class ViewDatapoints(Base):
1290
+ __tablename__ = "datapoints"
1291
+
1292
+ cell_code = Column(String, primary_key=True)
1293
+ table_code = Column(String)
1294
+ row_code = Column(String)
1295
+ column_code = Column(String)
1296
+ sheet_code = Column(String)
1297
+ variable_id = Column(String)
1298
+ data_type = Column(String)
1299
+ table_vid = Column(Integer)
1300
+ property_id = Column(Integer)
1301
+ start_release = Column(Integer)
1302
+ end_release = Column(Integer)
1303
+ cell_id = Column(Integer)
1304
+ context_id = Column(Integer)
1305
+ variable_vid = Column(String)
1306
+
1307
+ @classmethod
1308
+ def _create_base_query_with_aliases(cls, session):
1309
+ """
1310
+ Create the base query with all aliases and joins.
1311
+ Returns query and the aliases for reuse in other methods.
1312
+ """
1313
+ # Create aliases for the header version subqueries
1314
+ hvr_subq = aliased(HeaderVersion)
1315
+ hvc_subq = aliased(HeaderVersion)
1316
+ hvs_subq = aliased(HeaderVersion)
1317
+
1318
+ tvh_row = aliased(TableVersionHeader)
1319
+ tvh_col = aliased(TableVersionHeader)
1320
+ tvh_sheet = aliased(TableVersionHeader)
1321
+
1322
+ # Build the base query with all joins
1323
+ query = session.query().select_from(TableVersionCell)
1324
+
1325
+ # Join with TableVersion
1326
+ query = query.join(
1327
+ TableVersion,
1328
+ and_(
1329
+ TableVersionCell.tablevid == TableVersion.tablevid,
1330
+ TableVersionCell.isvoid == False
1331
+ )
1332
+ )
1333
+
1334
+ # Join with ModuleVersionComposition and ModuleVersion
1335
+ query = query.join(
1336
+ ModuleVersionComposition,
1337
+ TableVersion.tablevid == ModuleVersionComposition.tablevid
1338
+ )
1339
+
1340
+ query = query.join(
1341
+ ModuleVersion,
1342
+ ModuleVersionComposition.modulevid == ModuleVersion.modulevid
1343
+ )
1344
+
1345
+ # Left join with VariableVersion
1346
+ query = query.outerjoin(
1347
+ VariableVersion,
1348
+ TableVersionCell.variablevid == VariableVersion.variablevid
1349
+ )
1350
+
1351
+ # Left join with Property
1352
+ query = query.outerjoin(
1353
+ Property,
1354
+ VariableVersion.propertyid == Property.propertyid
1355
+ )
1356
+
1357
+ # Left join with DataType
1358
+ query = query.outerjoin(
1359
+ DataType,
1360
+ Property.datatypeid == DataType.datatypeid
1361
+ )
1362
+
1363
+ # Join with Cell
1364
+ query = query.join(
1365
+ Cell,
1366
+ TableVersionCell.cellid == Cell.cellid
1367
+ )
1368
+
1369
+ # Left join for Row headers (hvr)
1370
+ query = query.outerjoin(
1371
+ tvh_row,
1372
+ tvh_row.tablevid == TableVersion.tablevid
1373
+ )
1374
+
1375
+ query = query.outerjoin(
1376
+ hvr_subq,
1377
+ and_(
1378
+ tvh_row.headervid == hvr_subq.headervid,
1379
+ hvr_subq.headerid == Cell.rowid,
1380
+ hvr_subq.endreleaseid.is_(None)
1381
+ )
1382
+ )
1383
+
1384
+ # Left join for Column headers (hvc)
1385
+ query = query.outerjoin(
1386
+ tvh_col,
1387
+ tvh_col.tablevid == TableVersion.tablevid
1388
+ )
1389
+
1390
+ query = query.outerjoin(
1391
+ hvc_subq,
1392
+ and_(
1393
+ tvh_col.headervid == hvc_subq.headervid,
1394
+ hvc_subq.headerid == Cell.columnid,
1395
+ hvc_subq.endreleaseid.is_(None)
1396
+ )
1397
+ )
1398
+
1399
+ # Left join for Sheet headers (hvs)
1400
+ query = query.outerjoin(
1401
+ tvh_sheet,
1402
+ tvh_sheet.tablevid == TableVersion.tablevid
1403
+ )
1404
+
1405
+ query = query.outerjoin(
1406
+ hvs_subq,
1407
+ and_(
1408
+ tvh_sheet.headervid == hvs_subq.headervid,
1409
+ hvs_subq.headerid == Cell.sheetid,
1410
+ hvs_subq.endreleaseid.is_(None)
1411
+ )
1412
+ )
1413
+
1414
+ # Return query and aliases for reuse
1415
+ aliases = {
1416
+ 'hvr': hvr_subq,
1417
+ 'hvc': hvc_subq,
1418
+ 'hvs': hvs_subq,
1419
+ 'tvh_row': tvh_row,
1420
+ 'tvh_col': tvh_col,
1421
+ 'tvh_sheet': tvh_sheet
1422
+ }
1423
+
1424
+ return query, aliases
1425
+
1426
+ @classmethod
1427
+ def create_view_query(cls, session):
1428
+ """Create the full datapoints view query with all columns."""
1429
+ query, aliases = cls._create_base_query_with_aliases(session)
1430
+
1431
+ # Add the column selections
1432
+ query = query.add_columns(
1433
+ TableVersionCell.cellcode.label('cell_code'),
1434
+ TableVersion.code.label('table_code'),
1435
+ aliases['hvr'].code.label('row_code'),
1436
+ aliases['hvc'].code.label('column_code'),
1437
+ aliases['hvs'].code.label('sheet_code'),
1438
+ VariableVersion.variableid.label('variable_id'),
1439
+ DataType.code.label('data_type'),
1440
+ TableVersion.tablevid.label('table_vid'),
1441
+ Property.propertyid.label('property_id'),
1442
+ ModuleVersion.startreleaseid.label('start_release'),
1443
+ ModuleVersion.endreleaseid.label('end_release'),
1444
+ TableVersionCell.cellid.label('cell_id'),
1445
+ VariableVersion.contextid.label('context_id'),
1446
+ VariableVersion.variablevid.label('variable_vid')
1447
+ )
1448
+
1449
+ # Make it distinct
1450
+ query = query.distinct()
1451
+
1452
+ return query
1453
+
1454
+ @classmethod
1455
+ def count_all(cls, session):
1456
+ return cls.create_view_query(session).count()
1457
+
1458
+ @classmethod
1459
+ def get_filtered_datapoints(cls, session, table: str, table_info: dict, release_id: int = None):
1460
+ query, aliases = cls._create_base_query_with_aliases(session)
1461
+
1462
+ # Add the column selections
1463
+ query = query.add_columns(
1464
+ TableVersionCell.cellcode.label('cell_code'),
1465
+ TableVersion.code.label('table_code'),
1466
+ aliases['hvr'].code.label('row_code'),
1467
+ aliases['hvc'].code.label('column_code'),
1468
+ aliases['hvs'].code.label('sheet_code'),
1469
+ VariableVersion.variableid.label('variable_id'),
1470
+ DataType.code.label('data_type'),
1471
+ TableVersion.tablevid.label('table_vid'),
1472
+ Property.propertyid.label('property_id'),
1473
+ ModuleVersion.startreleaseid.label('start_release'),
1474
+ ModuleVersion.endreleaseid.label('end_release'),
1475
+ TableVersionCell.cellid.label('cell_id'),
1476
+ VariableVersion.contextid.label('context_id'),
1477
+ VariableVersion.variablevid.label('variable_vid')
1478
+ ).distinct()
1479
+
1480
+ # Apply table filter
1481
+ query = query.filter(TableVersion.code == table)
1482
+
1483
+ # Apply dimension filters
1484
+ mapping_dictionary = {
1485
+ 'rows': aliases['hvr'].code,
1486
+ 'cols': aliases['hvc'].code,
1487
+ 'sheets': aliases['hvs'].code
1488
+ }
1489
+
1490
+ for key, values in table_info.items():
1491
+ if values is not None and key in mapping_dictionary:
1492
+ column = mapping_dictionary[key]
1493
+ if '-' in values[0]:
1494
+ low_limit, high_limit = values[0].split('-')
1495
+ query = query.filter(column.between(low_limit, high_limit))
1496
+ elif values[0] == '*':
1497
+ continue
1498
+ else:
1499
+ query = query.filter(column.in_(values))
1500
+
1501
+ if release_id:
1502
+ query = filter_by_release(query, ModuleVersion.startreleaseid, ModuleVersion.endreleaseid, release_id)
1503
+
1504
+ return pd.read_sql_query(query.statement, session.connection())
1505
+
1506
+
1507
+ @classmethod
1508
+ def get_datapoints_count(cls, session):
1509
+ """Get count of datapoints using the view query"""
1510
+ query = cls.create_view_query(session)
1511
+ return query.count()
1512
+
1513
+ @classmethod
1514
+ def get_datapoints_sample(cls, session, limit=1000):
1515
+ """Get a sample of datapoints"""
1516
+ query = cls.create_view_query(session)
1517
+ return pd.read_sql_query(
1518
+ query.limit(limit).statement,
1519
+ session.connection()
1520
+ )
1521
+
1522
+ @classmethod
1523
+ def export_datapoints_query(cls, session):
1524
+ """Get the compiled SQL query for the datapoints view"""
1525
+ query = cls.create_view_query(session)
1526
+ return str(query.statement.compile(
1527
+ dialect=session.bind.dialect,
1528
+ compile_kwargs={"literal_binds": True}
1529
+ ))
1530
+ @classmethod
1531
+ def get_all_datapoints(cls, session):
1532
+ query = cls.create_view_query(session)
1533
+ return pd.read_sql_query(query.statement, session.connection())
1534
+
1535
+ @classmethod
1536
+ def get_table_data(cls, session, table, rows=None, columns=None, sheets=None, release_id=None):
1537
+ query, aliases = cls._create_base_query_with_aliases(session)
1538
+
1539
+ # Select only needed columns
1540
+ query = query.add_columns(
1541
+ TableVersionCell.cellcode.label('cell_code'),
1542
+ TableVersion.code.label('table_code'),
1543
+ aliases['hvr'].code.label('row_code'),
1544
+ aliases['hvc'].code.label('column_code'),
1545
+ aliases['hvs'].code.label('sheet_code'),
1546
+ VariableVersion.variableid.label('variable_id'),
1547
+ DataType.code.label('data_type'),
1548
+ TableVersion.tablevid.label('table_vid'),
1549
+ TableVersionCell.cellid.label('cell_id')
1550
+ ).distinct()
1551
+
1552
+ query = query.filter(TableVersion.code == table)
1553
+
1554
+ if rows is not None:
1555
+ query = filter_elements(query, aliases['hvr'].code, rows)
1556
+ if columns is not None:
1557
+ query = filter_elements(query, aliases['hvc'].code, columns)
1558
+ if sheets is not None:
1559
+ query = filter_elements(query, aliases['hvs'].code, sheets)
1560
+
1561
+ query = filter_by_release(query, ModuleVersion.startreleaseid, ModuleVersion.endreleaseid, release_id)
1562
+
1563
+ data = pd.read_sql_query(query.statement, session.connection())
1564
+
1565
+ data = _check_ranges_values_are_present(data, 'row_code', rows)
1566
+ data = _check_ranges_values_are_present(data, 'column_code', columns)
1567
+ data = _check_ranges_values_are_present(data, 'sheet_code', sheets)
1568
+
1569
+ return data
1570
+
1571
+ @classmethod
1572
+ def get_from_property(cls, session, property_id, release_id=None):
1573
+ query, aliases = cls._create_base_query_with_aliases(session)
1574
+
1575
+ query = query.add_columns(
1576
+ TableVersionCell.cellcode.label('cell_code'),
1577
+ TableVersion.code.label('table_code'),
1578
+ aliases['hvr'].code.label('row_code'),
1579
+ aliases['hvc'].code.label('column_code'),
1580
+ aliases['hvs'].code.label('sheet_code'),
1581
+ VariableVersion.variableid.label('variable_id'),
1582
+ DataType.code.label('data_type'),
1583
+ TableVersion.tablevid.label('table_vid')
1584
+ ).distinct()
1585
+
1586
+ query = query.filter(Property.propertyid == property_id)
1587
+ query = filter_by_release(query, ModuleVersion.startreleaseid, ModuleVersion.endreleaseid, release_id)
1588
+
1589
+ return pd.read_sql_query(query.statement, session.connection())
1590
+
1591
+ @classmethod
1592
+ def get_from_table_vid(cls, session, table_version_id):
1593
+ query = cls.create_view_query(session)
1594
+ query = query.filter(TableVersion.tablevid == table_version_id)
1595
+ query = filter_by_release(query, ModuleVersion.startreleaseid, ModuleVersion.endreleaseid, release_id=None)
1596
+ return pd.read_sql_query(query.statement, session.connection())
1597
+
1598
+ @classmethod
1599
+ def get_from_table_code(cls, session, table_code, release_id=None):
1600
+ query = cls.create_view_query(session)
1601
+ query = query.filter(TableVersion.code == table_code)
1602
+ query = filter_by_release(query, ModuleVersion.startreleaseid, ModuleVersion.endreleaseid, release_id)
1603
+ return pd.read_sql_query(query.statement, session.connection())
1604
+
1605
+ @classmethod
1606
+ def get_from_table_vid_with_is_nullable(cls, session, table_version_id):
1607
+ query, aliases = cls._create_base_query_with_aliases(session)
1608
+
1609
+ query = query.add_columns(
1610
+ TableVersionCell.cellcode.label('cell_code'),
1611
+ TableVersion.code.label('table_code'),
1612
+ aliases['hvr'].code.label('row_code'),
1613
+ aliases['hvc'].code.label('column_code'),
1614
+ aliases['hvs'].code.label('sheet_code'),
1615
+ VariableVersion.variableid.label('variable_id'),
1616
+ DataType.code.label('data_type'),
1617
+ TableVersion.tablevid.label('table_vid'),
1618
+ Property.propertyid.label('property_id'),
1619
+ ModuleVersion.startreleaseid.label('start_release'),
1620
+ ModuleVersion.endreleaseid.label('end_release'),
1621
+ TableVersionCell.cellid.label('cell_id'),
1622
+ VariableVersion.contextid.label('context_id'),
1623
+ VariableVersion.variablevid.label('variable_vid'),
1624
+ TableVersionCell.isnullable # Add the nullable column
1625
+ ).distinct()
1626
+
1627
+ query = query.filter(TableVersion.tablevid == table_version_id)
1628
+ return pd.read_sql_query(query.statement, session.connection())
1629
+
1630
+ @classmethod
1631
+ def get_from_subcategory_properties(cls, session, properties, release_id):
1632
+ query, aliases = cls._create_base_query_with_aliases(session)
1633
+
1634
+ # Add ContextComposition join
1635
+ query = query.join(
1636
+ ContextComposition,
1637
+ and_(
1638
+ ContextComposition.contextid == VariableVersion.contextid,
1639
+ ContextComposition.propertyid.in_(properties)
1640
+ )
1641
+ )
1642
+
1643
+ query = query.add_columns(
1644
+ TableVersion.code.label('table_code'),
1645
+ aliases['hvr'].code.label('row_code'),
1646
+ aliases['hvc'].code.label('column_code'),
1647
+ aliases['hvs'].code.label('sheet_code'),
1648
+ Property.propertyid.label('property_id'),
1649
+ VariableVersion.contextid.label('context_id'),
1650
+ VariableVersion.variablevid.label('variable_vid'),
1651
+ ContextComposition.propertyid.label('subcategory_property'),
1652
+ TableVersionCell.cellid.label('cell_id'),
1653
+ DataType.code.label('data_type')
1654
+ ).distinct()
1655
+
1656
+ query = filter_by_release(query, ModuleVersion.startreleaseid, ModuleVersion.endreleaseid, release_id)
1657
+ return pd.read_sql_query(query.statement, session.connection())
1658
+
1659
+ @classmethod
1660
+ def filter_by_context_and_property(cls, session, context, property_key, release_id):
1661
+ query, aliases = cls._create_base_query_with_aliases(session)
1662
+
1663
+ query = query.add_columns(
1664
+ TableVersion.code.label('table_code'),
1665
+ aliases['hvr'].code.label('row_code'),
1666
+ aliases['hvc'].code.label('column_code'),
1667
+ aliases['hvs'].code.label('sheet_code'),
1668
+ Property.propertyid.label('property_id'),
1669
+ VariableVersion.contextid.label('context_id'),
1670
+ VariableVersion.variablevid.label('variable_vid'),
1671
+ TableVersionCell.cellid.label('cell_id')
1672
+ ).distinct()
1673
+
1674
+ query = query.filter(VariableVersion.contextid == context)
1675
+
1676
+ if property_key:
1677
+ query = query.filter(Property.propertyid == property_key)
1678
+
1679
+ query = filter_by_release(query, ModuleVersion.startreleaseid, ModuleVersion.endreleaseid, release_id)
1680
+ return pd.read_sql_query(query.statement, session.connection())
1681
+ class ViewKeyComponents(Base):
1682
+ __tablename__ = "key_components"
1683
+
1684
+ table_code = Column(String, primary_key=True)
1685
+ property_code = Column(String, primary_key=True)
1686
+ data_type = Column(String, primary_key=True)
1687
+ table_version_id = Column(Integer)
1688
+ start_release_ic = Column(Integer)
1689
+ end_release_ic = Column(Integer)
1690
+ start_release_mv = Column(Integer)
1691
+ end_release_mv = Column(Integer)
1692
+
1693
+ @classmethod
1694
+ def get_by_table(cls, session, table, release_id):
1695
+ query = session.query(cls.table_code, cls.property_code, cls.data_type)
1696
+ query = query.filter_by(table_code=table)
1697
+ query = filter_by_release(query, cls.start_release_ic, cls.end_release_ic, release_id)
1698
+ query = filter_by_release(query, cls.start_release_mv, cls.end_release_mv, release_id)
1699
+ data = pd.read_sql_query(query.statement, session.connection())
1700
+ return data
1701
+
1702
+ @classmethod
1703
+ def get_from_several_tables(cls, session, tables, release_id):
1704
+ query = session.query(cls.table_code, cls.property_code, cls.data_type)
1705
+ query = query.filter(cls.table_code.in_(tables))
1706
+ query = filter_by_release(query, cls.start_release_ic, cls.end_release_ic, release_id)
1707
+ query = filter_by_release(query, cls.start_release_mv, cls.end_release_mv, release_id)
1708
+ data = pd.read_sql_query(query.statement, session.connection())
1709
+ return data
1710
+
1711
+ @classmethod
1712
+ def get_by_table_version_id(cls, session, table_version_id):
1713
+ query = session.query(cls.table_code, cls.property_code, cls.data_type)
1714
+ query = query.filter_by(table_version_id=table_version_id)
1715
+ return pd.read_sql_query(query.statement, session.connection())
1716
+
1717
+ class ViewOpenKeys(Base):
1718
+ __tablename__ = "open_keys"
1719
+
1720
+ property_code = Column(String, primary_key=True)
1721
+ data_type = Column(String, primary_key=True)
1722
+ start_release = Column(Integer)
1723
+ end_release = Column(Integer)
1724
+
1725
+ @classmethod
1726
+ def get_keys(cls, session, dimension_codes, release_id):
1727
+ query = session.query(cls.property_code, cls.data_type)
1728
+ query = query.filter(cls.property_code.in_(dimension_codes))
1729
+ query = filter_by_release(query, cls.start_release, cls.end_release, release_id)
1730
+ data = pd.read_sql_query(query.statement, session.connection())
1731
+ return data
1732
+
1733
+ @classmethod
1734
+ def get_all_keys(cls, session, release_id):
1735
+ query = session.query(cls.property_code, cls.data_type)
1736
+ query = filter_by_release(query, cls.start_release, cls.end_release, release_id)
1737
+ data = pd.read_sql_query(query.statement, session.connection())
1738
+ return data
1739
+
1740
+ class ViewDataTypes(Base):
1741
+ __tablename__ = "data_types"
1742
+
1743
+ datapoint = Column(String, primary_key=True)
1744
+ data_type = Column(String, primary_key=True)
1745
+ start_release = Column(Integer)
1746
+ end_release = Column(Integer)
1747
+
1748
+ @classmethod
1749
+ def get_data_types(cls, session, datapoints, release_id):
1750
+ results = []
1751
+ batch_size = 2000
1752
+ batch_start = 0
1753
+
1754
+ while batch_start < len(datapoints):
1755
+ batch_end = batch_start + batch_size
1756
+ datapoints_batch = datapoints[batch_start:batch_end]
1757
+ query = session.query(cls.datapoint, cls.data_type)
1758
+ query = filter_by_release(query, cls.start_release, cls.end_release, release_id)
1759
+ query = query.filter(cls.datapoint.in_(datapoints_batch))
1760
+ results.append(pd.read_sql_query(query.statement, session.connection()))
1761
+ batch_start += batch_size
1762
+
1763
+ data = pd.concat(results, axis=0)
1764
+ return data
1765
+
1766
+ class ViewSubcategoryItemInfo(Base):
1767
+ __tablename__ = "subcategory_info"
1768
+
1769
+ subcategory_id = Column(Integer, primary_key=True)
1770
+ item_code = Column(String, primary_key=True)
1771
+ is_default_item = Column(Boolean)
1772
+ parent_item_code = Column(String)
1773
+ ordering = Column(Integer)
1774
+ arithmetic_operator = Column(String, nullable=True)
1775
+ comparison_symbol = Column(String, nullable=True)
1776
+ start_release_id = Column(Integer)
1777
+ end_release_id = Column(Integer)
1778
+
1779
+ @classmethod
1780
+ def get_info(cls, session, subcategory_id, release_id=None):
1781
+ query = session.query(cls.item_code, cls.is_default_item, cls.parent_item_code,
1782
+ cls.ordering,
1783
+ cls.arithmetic_operator,
1784
+ cls.comparison_symbol).filter(cls.subcategory_id == subcategory_id)
1785
+ query = filter_by_release(query, cls.start_release_id, cls.end_release_id, release_id)
1786
+ query = query.order_by(cls.ordering)
1787
+ data = pd.read_sql_query(query.statement, session.connection())
1788
+ return data
1789
+
1790
+ class ViewHierarchyVariables(Base):
1791
+ __tablename__ = "hierarchy_variables"
1792
+
1793
+ subcategory_id = Column(Integer, primary_key=True)
1794
+ variable_vid = Column(Integer, primary_key=True)
1795
+ main_property_code = Column(String, primary_key=True)
1796
+ context_property_code = Column(String)
1797
+ cell_code = Column(String)
1798
+ item_code = Column(String)
1799
+ start_release_id = Column(Integer)
1800
+ end_release_id = Column(Integer)
1801
+
1802
+ @classmethod
1803
+ def get_subcategory_data(cls, session, subcategory_id, release_id):
1804
+ query = session.query(cls.cell_code, cls.variable_vid, cls.main_property_code,
1805
+ cls.context_property_code,
1806
+ cls.item_code).filter(
1807
+ cls.subcategory_id == subcategory_id)
1808
+ query = filter_by_release(query, cls.start_release_id, cls.end_release_id, release_id)
1809
+ data = pd.read_sql_query(query.statement, session.connection())
1810
+ return data
1811
+
1812
+ class ViewHierarchyVariablesContext(Base):
1813
+ __tablename__ = "hierarchy_variables_context"
1814
+
1815
+ variable_vid = Column(Integer, primary_key=True)
1816
+ context_property_code = Column(String, primary_key=True)
1817
+ item_code = Column(String)
1818
+ start_release_id = Column(Integer)
1819
+ end_release_id = Column(Integer)
1820
+
1821
+ @classmethod
1822
+ def get_context_from_variables(cls, session, variables: List[int], release_id=None):
1823
+ # Make batches of 1000 variables
1824
+ results = []
1825
+ batch_size = 1000
1826
+ for i in range(0, len(variables), batch_size):
1827
+ batch_end = i + batch_size
1828
+ variables_batch = variables[i:batch_end]
1829
+ query = session.query(cls.variable_vid, cls.context_property_code, cls.item_code).filter(
1830
+ cls.variable_vid.in_(variables_batch))
1831
+ query = filter_by_release(query, cls.start_release_id, cls.end_release_id, release_id)
1832
+ results.append(pd.read_sql_query(query.statement, session.connection()))
1833
+ data = pd.concat(results, axis=0)
1834
+ # Removing duplicates to avoid issues later with default values
1835
+ data = data.drop_duplicates(keep='first').reset_index(drop=True)
1836
+ return data
1837
+
1838
+ class ViewHierarchyPreconditions(Base):
1839
+ __tablename__ = "hierarchy_preconditions"
1840
+
1841
+ expression = Column(String, primary_key=True)
1842
+ operation_code = Column(String, primary_key=True)
1843
+ variable_code = Column(String, primary_key=True)
1844
+
1845
+ @classmethod
1846
+ def get_preconditions(cls, session):
1847
+ query = session.query(cls)
1848
+ return pd.read_sql_query(query.statement, session.connection())
1849
+
1850
+ class ViewOperations(Base):
1851
+ __tablename__ = "operation_list"
1852
+
1853
+ operation_version_id = Column(Integer, primary_key=True)
1854
+ operation_code = Column(String)
1855
+ expression = Column(String)
1856
+ start_release = Column(Integer)
1857
+ end_release = Column(Integer)
1858
+ precondition_operation_version_id = Column(Integer)
1859
+
1860
+ @classmethod
1861
+ def get_operations(cls, session):
1862
+ query = session.query(cls).distinct()
1863
+ operations = pd.read_sql_query(query.statement, session.connection())
1864
+ return operations.to_dict(orient="records")
1865
+
1866
+ @classmethod
1867
+ def get_expression_from_operation_code(cls, session, operation_code):
1868
+ query = session.query(cls.expression).filter(cls.operation_code == operation_code)
1869
+ query = filter_by_release(query, cls.start_release, cls.end_release, None)
1870
+ return query.one_or_none()
1871
+
1872
+ @classmethod
1873
+ def get_preconditions_used(cls, session):
1874
+ query = session.query(cls)
1875
+ preconditions = query.filter(cls.operation_version_id.is_not(None)).distinct().all()
1876
+ preconditions_ids = list(set([p.precondition_operation_version_id for p in
1877
+ query.filter(cls.precondition_operation_version_id.is_not(None)).distinct().all()]))
1878
+ query = session.query(cls)
1879
+
1880
+ query = query.filter(cls.operation_version_id.in_(preconditions_ids)).distinct()
1881
+ preconditions = pd.read_sql_query(query.statement, session.connection())
1882
+
1883
+ return preconditions.to_dict(orient="records")
1884
+
1885
+ class ViewModules(Base):
1886
+ __tablename__ = "module_from_table"
1887
+
1888
+ module_code = Column(String, primary_key=True)
1889
+ table_code = Column(String, primary_key=True)
1890
+ from_date = Column(Date)
1891
+ to_date = Column(Date)
1892
+
1893
+ @classmethod
1894
+ def get_all_modules(cls, session):
1895
+ query = session.query(cls.module_code, cls.table_code).distinct()
1896
+ return pd.read_sql_query(query.statement, session.connection())
1897
+
1898
+ @classmethod
1899
+ def get_modules(cls, session, tables, release_id=None):
1900
+ query = session.query(cls.module_code, cls.table_code)
1901
+ query = query.filter(cls.table_code.in_(tables))
1902
+ result = query.all()
1903
+ if len(result) == 0:
1904
+ return []
1905
+ module_list = [r[0] for r in result]
1906
+ return list(set(module_list))
1907
+
1908
+ class ViewOperationFromModule(Base):
1909
+ __tablename__ = "operations_versions_from_module_version"
1910
+
1911
+ module_version_id = Column(Integer, primary_key=True)
1912
+ operation_version_id = Column(Integer, primary_key=True)
1913
+ module_code = Column(String)
1914
+ from_date = Column(Date)
1915
+ to_date = Column(Date)
1916
+ expression = Column(String)
1917
+ operation_code = Column(String)
1918
+ precondition_operation_version_id = Column(Integer)
1919
+ is_active = Column(Boolean, nullable=False)
1920
+ severity = Column(String(20), nullable=False)
1921
+ operation_scope_id = Column(Integer)
1922
+
1923
+ @classmethod
1924
+ def get_operations(cls, session, module_code, ref_date):
1925
+ query = session.query(
1926
+ cls.module_code, cls.from_date, cls.to_date, cls.expression, cls.operation_code, cls.operation_version_id)
1927
+ query = query.filter(cls.module_code == module_code)
1928
+ query = filter_by_date(query, cls.from_date, cls.to_date, ref_date)
1929
+ return pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
1930
+
1931
+ @classmethod
1932
+ def get_module_version_id_from_operation_vid(cls, session, operation_version_id):
1933
+ query = session.query(cls.module_version_id, cls.module_code, cls.from_date, cls.to_date)
1934
+ query = query.filter(cls.operation_version_id == operation_version_id).distinct()
1935
+ return pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
1936
+
1937
+ @classmethod
1938
+ def get_operations_from_moduleversion_id(cls, session, module_version_id, with_preconditions=True, with_errors=False):
1939
+ query = session.query(
1940
+ cls.module_code, cls.from_date, cls.to_date, cls.expression, cls.operation_code, cls.operation_version_id,
1941
+ cls.precondition_operation_version_id, cls.is_active, cls.severity)
1942
+ query = query.filter(cls.module_version_id == module_version_id).distinct()
1943
+ reference = pd.read_sql_query(query.statement, session.connection())
1944
+ not_errors = []
1945
+ preconditions_to_remove = []
1946
+ if not with_errors:
1947
+ not_errors = session.query(OperationNode.nodeid.label('operation_version_id')).distinct()
1948
+ not_errors = pd.read_sql_query(not_errors.statement, session.connection())
1949
+ not_errors = list(not_errors['operation_version_id'])
1950
+ reference = reference[reference['operation_version_id'].isin(not_errors)]
1951
+ if not with_preconditions:
1952
+ preconditions = session.query(ViewPreconditionInfo.operation_version_id).distinct()
1953
+ preconditions = pd.read_sql_query(preconditions.statement, session.connection())
1954
+ preconditions_to_remove = list(preconditions['operation_version_id'])
1955
+ reference = reference[~reference['operation_version_id'].isin(preconditions_to_remove)]
1956
+
1957
+ return reference.to_dict(orient="records")
1958
+
1959
+ class ViewOperationInfo(Base):
1960
+ __tablename__ = "operation_info"
1961
+
1962
+ operation_node_id = Column(Integer, primary_key=True)
1963
+ operation_version_id = Column(Integer)
1964
+ parent_node_id = Column(Integer)
1965
+ operator_id = Column(Integer)
1966
+ symbol = Column(String(20))
1967
+ argument = Column(String(50))
1968
+ operator_argument_order = Column(Integer)
1969
+ is_leaf = Column(Boolean, nullable=False)
1970
+ scalar = Column(String)
1971
+ operand_reference_id = Column(Integer, nullable=False)
1972
+ operand_reference = Column(String)
1973
+ x = Column(Integer)
1974
+ y = Column(Integer)
1975
+ z = Column(Integer)
1976
+ item_id = Column(Integer)
1977
+ property_id = Column(Integer)
1978
+ variable_id = Column(Integer)
1979
+ use_interval_arithmetics = Column(Boolean, nullable=False)
1980
+ fallback_value = Column(String(50))
1981
+
1982
+ @classmethod
1983
+ def get_operation_info(cls, session, operation_version_id):
1984
+ query = session.query(cls).filter(cls.operation_version_id == operation_version_id)
1985
+ return pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
1986
+
1987
+ @classmethod
1988
+ def get_operation_info_df(cls, session, operation_version_ids):
1989
+ rename_dict = {
1990
+ "operation_node_id": "NodeID",
1991
+ "operation_version_id": "OperationVID",
1992
+ "operator_id": "OperatorID",
1993
+ "operator_argument_order": "Order",
1994
+ "parent_node_id": "ParentNodeID",
1995
+ "symbol": "symbol",
1996
+ "argument": "argument",
1997
+ "operand_reference": "OperandReference",
1998
+ "use_interval_arithmetics": "UseIntervalArithmetics",
1999
+ "fallback_value": "FallbackValue",
2000
+ "operand_reference_id": "OperandReferenceId",
2001
+ "scalar": "Scalar",
2002
+ "is_leaf": "IsLeaf",
2003
+ "item_id": "ItemID",
2004
+ "property_id": "PropertyID",
2005
+ "variable_id": "VariableID"
2006
+ }
2007
+ query = session.query(cls).filter(cls.operation_version_id.in_(operation_version_ids))
2008
+ df = pd.read_sql_query(query.statement, session.connection())
2009
+ df = df.rename(columns=rename_dict)
2010
+ return df
2011
+
2012
+ class ViewTableInfo(Base):
2013
+ __tablename__ = "table_info"
2014
+
2015
+ table_code = Column(String, primary_key=True)
2016
+ table_version_id = Column(Integer, primary_key=True)
2017
+ table_id = Column(Integer)
2018
+ module_code = Column(String)
2019
+ module_version_id = Column(Integer)
2020
+ variable_id = Column(Integer)
2021
+ variable_version_id = Column(Integer)
2022
+
2023
+ @classmethod
2024
+ def get_tables_from_module_code(cls, session, module_code):
2025
+ query = session.query(cls.table_code, cls.table_version_id).filter(cls.module_code == module_code).distinct()
2026
+ return pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
2027
+
2028
+ @classmethod
2029
+ def get_tables_from_module_version(cls, session, module_version_id):
2030
+ query = session.query(cls.table_code, cls.table_version_id).filter(cls.module_version_id == module_version_id).distinct()
2031
+ return pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
2032
+
2033
+ @classmethod
2034
+ def get_variables_from_table_code(cls, session, table_code, to_dict=True):
2035
+ query = session.query(cls.variable_id, cls.variable_version_id).filter(cls.table_code == table_code)
2036
+ data = pd.read_sql_query(query.statement, session.connection())
2037
+ if to_dict:
2038
+ return data.to_dict(orient="records")
2039
+ return data
2040
+
2041
+ @classmethod
2042
+ def get_variables_from_table_version(cls, session, table_version_id):
2043
+ query = session.query(cls.variable_id, cls.variable_version_id).filter(cls.table_version_id == table_version_id)
2044
+ return pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
2045
+
2046
+ @classmethod
2047
+ def get_intra_module_variables(cls, session):
2048
+ query = session.query(cls.variable_version_id, cls.module_code).distinct()
2049
+ module_data = pd.read_sql_query(query.statement, session.connection())
2050
+ intra_module_data = module_data.drop_duplicates(subset=["variable_version_id"], keep=False,
2051
+ ignore_index=True)
2052
+ del module_data
2053
+ intra_module_variables = intra_module_data['variable_version_id'].unique().tolist()
2054
+ del intra_module_data
2055
+ return intra_module_variables
2056
+
2057
+ @classmethod
2058
+ def is_intra_module(cls, session, table_codes):
2059
+ query = session.query(cls.table_code, cls.module_code).distinct().filter(cls.table_code.in_(table_codes))
2060
+ module_data = pd.read_sql_query(query.statement, session.connection())
2061
+
2062
+ all_combinations = module_data.groupby("table_code")["module_code"].apply(list).reset_index(
2063
+ drop=False).to_dict(orient="records")
2064
+
2065
+ intersect_set = None
2066
+ for combination in all_combinations:
2067
+ if intersect_set is None:
2068
+ intersect_set = set(combination['module_code'])
2069
+ else:
2070
+ intersect_set = intersect_set.intersection(set(combination['module_code']))
2071
+
2072
+ if intersect_set is None:
2073
+ return False
2074
+ return len(intersect_set) > 0
2075
+
2076
+ class ViewPreconditionInfo(Base):
2077
+ __tablename__ = "precondition_info"
2078
+
2079
+ operation_node_id = Column(Integer, primary_key=True)
2080
+ operation_version_id = Column(Integer)
2081
+ operation_code = Column(String)
2082
+ variable_type = Column(String)
2083
+ variable_id = Column(Integer)
2084
+ variable_version_id = Column(Integer)
2085
+ variable_code = Column(String)
2086
+
2087
+ @classmethod
2088
+ def get_preconditions(cls, session):
2089
+ query = session.query(cls.operation_version_id, cls.operation_code, cls.variable_code).distinct()
2090
+ return pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
2091
+
2092
+ @classmethod
2093
+ def get_precondition_code(cls, session, variable_version_id):
2094
+ query = session.query(cls.variable_code).filter(cls.variable_version_id == variable_version_id).distinct()
2095
+ return query.one()
2096
+
2097
+ class ViewHierarchyOperandReferenceInfo(Base):
2098
+ __tablename__ = "hierarchy_operand_reference"
2099
+
2100
+ operation_code = Column(String, primary_key=True)
2101
+ operation_node_id = Column(Integer, primary_key=True)
2102
+ cell_id = Column(Integer, primary_key=True)
2103
+ variable_id = Column(Integer)
2104
+
2105
+ @classmethod
2106
+ def get_operations(cls, session, cell_id):
2107
+ query = session.query(cls.operation_code, cls.operation_node_id).filter(cls.cell_id == cell_id).distinct()
2108
+ operations = pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
2109
+ return operations
2110
+
2111
+ @classmethod
2112
+ def get_hierarchy_operations(cls, session, var_id_list):
2113
+ query = session.query(cls).filter(cls.variable_id.in_(var_id_list))
2114
+ possible_op_codes = []
2115
+
2116
+ df = pd.read_sql_query(query.statement, session.connection())
2117
+ grouped_code = df.groupby("operation_code")
2118
+ for elto_k, elto_v in grouped_code.groups.items():
2119
+ if len(grouped_code.groups[elto_k]) == len(var_id_list):
2120
+ possible_op_codes.append(elto_k)
2121
+ return possible_op_codes
2122
+
2123
+ class ViewReportTypeOperandReferenceInfo(Base):
2124
+ __tablename__ = "report_type_operand_reference_info"
2125
+
2126
+ operation_code = Column(String, primary_key=True)
2127
+ operation_node_id = Column(Integer, primary_key=True)
2128
+ cell_id = Column(Integer, primary_key=True)
2129
+ variable_id = Column(Integer)
2130
+ report_type = Column(String)
2131
+ table_version_id = Column(Integer)
2132
+ table_version_vid = Column(Integer)
2133
+ sub_category_id = Column(Integer)
2134
+
2135
+ @classmethod
2136
+ def get_operations(cls, session, cell_id):
2137
+ query = session.query(cls.operation_code, cls.operation_node_id).filter(cls.cell_id == cell_id).distinct()
2138
+ operations = pd.read_sql_query(query.statement, session.connection()).to_dict(orient="records")
2139
+ return operations