invalid_category¶
This rule checks if the rows of a categorical column in a table have the
right values. A right value is one in the set of allowable values for
the categorical column. For example, the coll
column in the samples
table is a categorical column whose set of allowable values or
categories are comp3h
, comp8h
, flowPr
etc. The following samples
table row would fail validation,
Invalid Dataset ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ coll ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ flow │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
The following samples table row would pass validation,
Valid Dataset ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ coll ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ flowPr │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
For non-mandatory categorical columns, values representing missing are
also allowed. Assuming that coll
is not mandatory, the following table
should pass validation,
Valid Dataset ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ coll ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ NA │ │ │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
The second row contains an empty string.
Error report¶
The error report will have the following fields
errorType: invalid_category
tableName: The name of the table whose row has the invalid category
columnName The name of the column with the invalid category
rowNumber: The index of the table row with the error
row The row in the data that failed this validation rule
invalidValue: The invalid category value
validationRuleFields: The ODM data dictionary rule fields violated by this row
message: Invalid category <invalidValue> found in row <rowIndex> for column <columnName> in table <tableName>
Example
{ │ 'errors': [ │ │ { │ │ │ 'errorType': 'invalid_category', │ │ │ 'tableName': 'samples', │ │ │ 'columnName': 'coll', │ │ │ 'rowNumber': 1, │ │ │ 'row': { │ │ │ │ 'coll': 'flow' │ │ │ }, │ │ │ 'invalidValue': 'flow', │ │ │ 'validationRuleFields': [ │ │ │ │ { │ │ │ │ │ 'partID': 'coll', │ │ │ │ │ 'samples': 'header', │ │ │ │ │ 'dataType': 'categorical', │ │ │ │ │ 'mmaSet': 'collectCat' │ │ │ │ }, │ │ │ │ { │ │ │ │ │ 'partID': 'comp3h', │ │ │ │ │ 'setID': 'collectCat' │ │ │ │ }, │ │ │ │ { │ │ │ │ │ 'partID': 'comp8h', │ │ │ │ │ 'setID': 'collectCat' │ │ │ │ }, │ │ │ │ { │ │ │ │ │ 'partID': 'flowPr', │ │ │ │ │ 'setID': 'collectCat' │ │ │ │ } │ │ │ ], │ │ │ 'message': 'invalid_category rule violated in table samples, column coll, row(s) 1: Invalid category "flow"' │ │ } │ ], │ 'warnings': [] }
Rule metadata¶
The metadata for this rule is contained in two sheets:
The parts sheet which has information on whether a column is categorical and if it is, information on how to find the categories that are part of it
The sets sheet which contains information on the categories
The steps to use this meatdata are:
Filter the columns to only include those that are categorical. Categorical columns have a
dataType
value ofcategorical
.For each categorical column, identify the name of the set that has the categories for that column. The set name is stored in the
mmaSet
column.Use the sets sheet and the value of the
mmaSet
column to identify the categories. For each categorical column, filter the sets sheet to only include those rows whosesetID
column value is the same as themmaSet
value.In the filtered rows, the
partID
column contains the category values.
Example
Parts v2 ┏━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┓ ┃ partID ┃ partType ┃ samples ┃ sites ┃ measures ┃ dataType ┃ mmaSet ┃ status ┃ firstRele… ┃ lastUpda… ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━┩ │ samples │ tables │ NA │ NA │ NA │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ sites │ tables │ NA │ NA │ NA │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ measures │ tables │ NA │ NA │ NA │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ coll │ attribut… │ header │ NA │ NA │ categori… │ collectC… │ active │ 1.0.0 │ 2.0.0 │ │ comp3h │ categori… │ input │ NA │ NA │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ │ comp8h │ categori… │ input │ NA │ NA │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ │ flowPr │ categori… │ input │ NA │ NA │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ │ siteType… │ attribut… │ NA │ fK │ NA │ categori… │ siteType… │ active │ 1.0.0 │ 2.0.0 │ │ wwtpMuC │ categori… │ NA │ input │ NA │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ │ wwtpMuS │ categori… │ NA │ input │ NA │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ │ someOldC… │ categori… │ NA │ input │ NA │ varchar │ NA │ deprecia… │ 1.0.0 │ 2.0.0 │ │ tp24s │ categori… │ NA │ NA │ NA │ NA │ NA │ deprecia… │ 1.0.0 │ 2.0.0 │ │ measureID │ attribut… │ NA │ NA │ fK │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ │ cod │ categori… │ NA │ NA │ input │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ │ NA │ missingn… │ NA │ NA │ NA │ varchar │ NA │ active │ 1.0.0 │ 2.0.0 │ └───────────┴───────────┴─────────┴───────┴──────────┴───────────┴───────────┴───────────┴────────────┴───────────┘
Sets ┏━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓ ┃ setID ┃ partID ┃ firstReleased ┃ lastUpdated ┃ status ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩ │ collectCat │ comp3h │ 1.0.0 │ 2.0.0 │ active │ │ collectCat │ comp8h │ 1.0.0 │ 2.0.0 │ active │ │ collectCat │ flowPr │ 1.0.0 │ 2.0.0 │ active │ └────────────────────────┴────────────────┴─────────────────────────────┴─────────────────────────┴───────────────┘
Here, the name of the categorical column is coll
and its a column in
the samples
table. The set name is collectCat
which is used to
identify the category values in the sets sheet which are comp3h
,
comp8h
, and flowPr
.
Cerberus Schema¶
The generated cerberus object for the example above is shown below,
{ │ 'schemaVersion': '2.0.0', │ 'schema': { │ │ 'samples': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'coll': { │ │ │ │ │ │ 'allowed': [ │ │ │ │ │ │ │ 'comp3h', │ │ │ │ │ │ │ 'comp8h', │ │ │ │ │ │ │ 'flowPr' │ │ │ │ │ │ ], │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'invalid_category', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'coll', │ │ │ │ │ │ │ │ │ │ 'samples': 'header', │ │ │ │ │ │ │ │ │ │ 'dataType': 'categorical', │ │ │ │ │ │ │ │ │ │ 'mmaSet': 'collectCat' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'comp3h', │ │ │ │ │ │ │ │ │ │ 'setID': 'collectCat' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'comp8h', │ │ │ │ │ │ │ │ │ │ 'setID': 'collectCat' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'flowPr', │ │ │ │ │ │ │ │ │ │ 'setID': 'collectCat' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'samples', │ │ │ │ │ │ 'partType': 'tables' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ } │ } }
The metadata for this rule should include the following rows from the ODM dictionary:
The part definition for the column in the table
The sets definition for each category that forms the category set for the categorical column
Version 1¶
Generating the cerberus schema for version 1 requires the following information:
The columns that are part of the version 1 table
Whether the column is categorical and
If it is, the list of allowed categories
Information on point 1 can be found here.
To check whether a version 1 column is categorical, we can use the
version1Location
column. If the column has a value of
variableCategories
then the part was a category in version 1. We can
then look at the value of the version1Category
column to see the what
the category value was in version 1. For example, in the ODM parts
snippet below,
Parts v1 ┏━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━┳━━━━━━━━┳━━━━━━━┳━━━━━━━━┓ ┃ part… ┃ part… ┃ samp… ┃ sites ┃ meas… ┃ data… ┃ mmaS… ┃ vers… ┃ vers… ┃ vers… ┃ vers… ┃ status ┃ firs… ┃ lastU… ┃ ┡━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━╇━━━━━━━━╇━━━━━━━╇━━━━━━━━┩ │ samp… │ tabl… │ NA │ NA │ NA │ NA │ NA │ tabl… │ Samp… │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ sites │ tabl… │ NA │ NA │ NA │ NA │ NA │ tabl… │ Site │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ meas… │ tabl… │ NA │ NA │ NA │ NA │ NA │ tabl… │ WWMe… │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ coll │ attr… │ head… │ NA │ NA │ cate… │ coll… │ vari… │ Samp… │ Coll… │ NA │ active │ 1.0.0 │ 2.0.0 │ │ comp… │ cate… │ input │ NA │ NA │ varc… │ NA │ vari… │ Samp… │ Coll… │ Comp… │ active │ 1.0.0 │ 2.0.0 │ │ comp… │ cate… │ input │ NA │ NA │ varc… │ NA │ vari… │ Samp… │ Coll… │ Comp… │ active │ 1.0.0 │ 2.0.0 │ │ flow… │ cate… │ input │ NA │ NA │ varc… │ NA │ vari… │ Samp… │ Coll… │ Flow… │ active │ 1.0.0 │ 2.0.0 │ │ site… │ attr… │ NA │ fK │ NA │ cate… │ site… │ vari… │ Site │ type │ NA │ active │ 1.0.0 │ 2.0.0 │ │ wwtp… │ cate… │ NA │ input │ NA │ varc… │ NA │ vari… │ Site │ type │ wwtp… │ active │ 1.0.0 │ 2.0.0 │ │ wwtp… │ cate… │ NA │ input │ NA │ varc… │ NA │ vari… │ Site │ type │ wwtp… │ active │ 1.0.0 │ 2.0.0 │ │ some… │ cate… │ NA │ input │ NA │ varc… │ NA │ vari… │ Site │ type │ some… │ depre… │ 1.0.0 │ 2.0.0 │ │ tp24s │ cate… │ NA │ NA │ NA │ NA │ NA │ vari… │ Site │ Samp… │ cpTP… │ depre… │ 1.0.0 │ 2.0.0 │ │ meas… │ attr… │ NA │ NA │ fK │ varc… │ NA │ vari… │ WWMe… │ type │ NA │ active │ 1.0.0 │ 2.0.0 │ │ cod │ cate… │ NA │ NA │ input │ varc… │ NA │ vari… │ WWMe… │ type │ wqCO… │ active │ 1.0.0 │ 2.0.0 │ │ │ │ │ │ │ │ │ │ Site… │ │ wwCOD │ │ │ │ │ NA │ miss… │ NA │ NA │ NA │ varc… │ NA │ NA │ NA │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ └───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴───────┴────────┴───────┴────────┘
In the snippet above, for a version 1 variable, we check whether the
version1Category
column has a value. If it does then it is
categorical. We can then retreive the categories by looking at all the
unique version1Category
values for that variable. Keep in mind, that
there can be multiple categories encoded in a cell, with each value
seperated by a semi-colon.
The version 1 variable Collection
column has four categories,
Comp3h
, Comp8h
, FlowPR
, FlowRatePr
.
The corresponding cerberus schema for version 1 would be,
{ │ 'schemaVersion': '1.0.0', │ 'schema': { │ │ 'Sample': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'Collection': { │ │ │ │ │ │ 'allowed': [ │ │ │ │ │ │ │ 'Comp3h', │ │ │ │ │ │ │ 'Comp8h', │ │ │ │ │ │ │ 'FlowPr', │ │ │ │ │ │ │ 'FlowRatePr', │ │ │ │ │ │ │ 'other' │ │ │ │ │ │ ], │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'invalid_category', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'coll', │ │ │ │ │ │ │ │ │ │ 'dataType': 'categorical', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variables', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Sample', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'Collection' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'comp3h', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variableCategories', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Sample', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'Collection', │ │ │ │ │ │ │ │ │ │ 'version1Category': 'Comp3h' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'comp8h', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variableCategories', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Sample', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'Collection', │ │ │ │ │ │ │ │ │ │ 'version1Category': 'Comp8h' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'flowPr', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variableCategories', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Sample', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'Collection', │ │ │ │ │ │ │ │ │ │ 'version1Category': 'FlowPr;FlowRatePr' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'samples', │ │ │ │ │ │ 'partType': 'tables', │ │ │ │ │ │ 'version1Location': 'tables', │ │ │ │ │ │ 'version1Table': 'Sample' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ }, │ │ 'Site': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'type': { │ │ │ │ │ │ 'allowed': [ │ │ │ │ │ │ │ 'other', │ │ │ │ │ │ │ 'someOldCat1', │ │ │ │ │ │ │ 'wwtpMuC', │ │ │ │ │ │ │ 'wwtpMuS' │ │ │ │ │ │ ], │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'invalid_category', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'siteTypeID', │ │ │ │ │ │ │ │ │ │ 'dataType': 'categorical', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variables', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Site', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'type' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'wwtpMuC', │ │ │ │ │ │ │ │ │ │ 'version1Category': 'wwtpMuC', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variableCategories', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Site', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'type' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'wwtpMuS', │ │ │ │ │ │ │ │ │ │ 'version1Category': 'wwtpMuS', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variableCategories', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Site', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'type' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'someOldCat', │ │ │ │ │ │ │ │ │ │ 'version1Category': 'someOldCat1', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variableCategories', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Site', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'type' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'sites', │ │ │ │ │ │ 'partType': 'tables', │ │ │ │ │ │ 'version1Location': 'tables', │ │ │ │ │ │ 'version1Table': 'Site' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ }, │ │ 'WWMeasure': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'type': { │ │ │ │ │ │ 'allowed': [ │ │ │ │ │ │ │ 'other', │ │ │ │ │ │ │ 'wqCOD', │ │ │ │ │ │ │ 'wwCOD' │ │ │ │ │ │ ], │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'invalid_category', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'dataType': 'varchar', │ │ │ │ │ │ │ │ │ │ 'partID': 'measureID', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variables', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'WWMeasure', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'type' │ │ │ │ │ │ │ │ │ }, │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'cod', │ │ │ │ │ │ │ │ │ │ 'version1Category': 'wqCOD; wwCOD', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variableCategories', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'WWMeasure; SiteMeasure', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'type' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'measures', │ │ │ │ │ │ 'partType': 'tables', │ │ │ │ │ │ 'version1Location': 'tables', │ │ │ │ │ │ 'version1Table': 'WWMeasure' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ } │ } }
The meta field for the rule should include the same part rows and fields as version 2 with the following additions,
The
version1Location
,version1Table
, and version1Variable` columns added to all the rowsThe
version1Category
column added to the category parts