missing_mandatory_column¶
This rule checks if the rows of each table contains its mandatory
columns. For example, the addID
column is mandatory for the
addresses
table. The following address table row,
Invalid Dataset ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ addL2 ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ 123 Doe Street │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
would fail validation. The following address table row would pass validation,
Valid Dataset ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ ┃ addID ┃ addL2 ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ │ 1 │ 123 Doe Street │ └───────────────────────────────────┴─────────────────────────────────────────────────────────────────────────────┘
Error report¶
The error report will have the following fields
errorType: missing_mandatory_column
tableName: The name of the table containing the missing column
columnName The name of the missing column
rowNumber: The index of the table row with the error
row The dictionary containing the row
validationRuleFields: The ODM data dictionary rule fields violated by this row
message: Missing mandatory column <columnName> in table <tableName> in row number <rowIndex>
Example
{ │ 'errors': [ │ │ { │ │ │ 'errorType': 'missing_mandatory_column', │ │ │ 'tableName': 'addresses', │ │ │ 'columnName': 'addID', │ │ │ 'rowNumber': 1, │ │ │ 'row': { │ │ │ │ 'addL2': '123 Doe Street' │ │ │ }, │ │ │ 'validationRuleFields': [ │ │ │ │ { │ │ │ │ │ 'addresses': 'pK', │ │ │ │ │ 'partID': 'addID', │ │ │ │ │ 'addressesRequired': 'mandatory' │ │ │ │ } │ │ │ ], │ │ │ 'message': 'missing_mandatory_column rule violated in table addresses, column addID: Missing mandatory column addID' │ │ } │ ], │ 'warnings': [] }
Rule metadata¶
All the metadata for this rule is contained in the parts sheet in the data dictionary. The relevant columns are:
partID: Contains the name of a part
<table_name>: Used to indicate whether the part is associated with a table
Can have one of the following values:
pK: The part is a primary key for the table
fK: The part is a foreign key for the table
header: The part is the name of a column in the table
input
NA: The part is not applicable to the table
<table_name>Required: Used to indicate whether a column is mandatory for a table
Can have one of the following values:
mandatory: The column is mandatory
optional: The column is not mandatory
NA: The column is not applicable
Example
Parts v2 ┏━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓ ┃ partID ┃ partType ┃ addresses ┃ addressesR… ┃ contacts ┃ contactsRe… ┃ status ┃ firstReleas… ┃ lastUpdated ┃ ┡━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩ │ addresses │ tables │ NA │ NA │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ addID │ attributes │ pK │ mandatory │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ addL2 │ attributes │ header │ optional │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ contacts │ tables │ NA │ NA │ NA │ NA │ active │ 1.0.0 │ 2.0.0 │ │ contID │ attributes │ NA │ NA │ pK │ mandatory │ active │ 1.0.0 │ 2.0.0 │ └───────────┴────────────┴───────────┴─────────────┴──────────┴─────────────┴────────┴──────────────┴─────────────┘
Cerberus Schema¶
The generated cerberus object for the example above is shown below,
{ │ 'schemaVersion': '2.0.0', │ 'schema': { │ │ 'addresses': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'addID': { │ │ │ │ │ │ 'required': True, │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'missing_mandatory_column', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'addID', │ │ │ │ │ │ │ │ │ │ 'addresses': 'pK', │ │ │ │ │ │ │ │ │ │ 'addressesRequired': 'mandatory' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'addresses', │ │ │ │ │ │ 'partType': 'tables' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ }, │ │ 'contacts': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'contID': { │ │ │ │ │ │ 'required': True, │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'missing_mandatory_column', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'contID', │ │ │ │ │ │ │ │ │ │ 'contacts': 'pK', │ │ │ │ │ │ │ │ │ │ 'contactsRequired': 'mandatory' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'contacts', │ │ │ │ │ │ 'partType': 'tables' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ } │ } }
The data dictionary columns that should be included in the meta
field
are: * partID * <table_name> * <table_name>Required
Version 1¶
We need three pieces of information to make the cerberus schema for version 1:
The columns that are part of the version 1 table
The version 2 equivalent for each column
The version 2 equivalent for the table
Details for the above points can be found here
We then check if the version 2 equivalent column is mandatory in the version 2 equivalent table, if it is, then it should be mandatory in version 1. For example,
Parts v1 ┏━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┳━━━━━━━━┳━━━━━━━━┳━━━━━━━━━┓ ┃ partID ┃ partT… ┃ addres… ┃ addre… ┃ contac… ┃ conta… ┃ versio… ┃ versi… ┃ versio… ┃ status ┃ first… ┃ lastUp… ┃ ┡━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━╇━━━━━━━━╇━━━━━━━━╇━━━━━━━━━┩ │ addres… │ tables │ NA │ NA │ NA │ NA │ tables │ Addre… │ NA │ active │ 1.0.0 │ 2.0.0 │ │ addID │ attri… │ pK │ manda… │ NA │ NA │ variab… │ Addre… │ Addres… │ active │ 1.0.0 │ 2.0.0 │ │ addL2 │ attri… │ header │ optio… │ NA │ NA │ variab… │ Addre… │ addres… │ active │ 1.0.0 │ 2.0.0 │ │ contac… │ tables │ NA │ NA │ NA │ NA │ tables │ Conta… │ NA │ active │ 1.0.0 │ 2.0.0 │ │ contID │ attri… │ NA │ NA │ pK │ manda… │ variab… │ Conta… │ Contac… │ active │ 1.0.0 │ 2.0.0 │ └─────────┴────────┴─────────┴────────┴─────────┴────────┴─────────┴────────┴─────────┴────────┴────────┴─────────┘
The corresponding version 1 cerberus schema is shown below,
{ │ 'schemaVersion': '1.0.0', │ 'schema': { │ │ 'Address': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'AddressId': { │ │ │ │ │ │ 'required': True, │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'missing_mandatory_column', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'addID', │ │ │ │ │ │ │ │ │ │ 'addresses': 'pK', │ │ │ │ │ │ │ │ │ │ 'addressesRequired': 'mandatory', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variables', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Address', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'AddressId' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'addresses', │ │ │ │ │ │ 'partType': 'tables', │ │ │ │ │ │ 'version1Location': 'tables', │ │ │ │ │ │ 'version1Table': 'Address' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ }, │ │ 'Contact': { │ │ │ 'type': 'list', │ │ │ 'schema': { │ │ │ │ 'type': 'dict', │ │ │ │ 'schema': { │ │ │ │ │ 'ContactId': { │ │ │ │ │ │ 'required': True, │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ 'ruleID': 'missing_mandatory_column', │ │ │ │ │ │ │ │ 'meta': [ │ │ │ │ │ │ │ │ │ { │ │ │ │ │ │ │ │ │ │ 'partID': 'contID', │ │ │ │ │ │ │ │ │ │ 'contacts': 'pK', │ │ │ │ │ │ │ │ │ │ 'contactsRequired': 'mandatory', │ │ │ │ │ │ │ │ │ │ 'version1Location': 'variables', │ │ │ │ │ │ │ │ │ │ 'version1Table': 'Contact', │ │ │ │ │ │ │ │ │ │ 'version1Variable': 'ContactId' │ │ │ │ │ │ │ │ │ } │ │ │ │ │ │ │ │ ] │ │ │ │ │ │ │ } │ │ │ │ │ │ ] │ │ │ │ │ } │ │ │ │ }, │ │ │ │ 'meta': [ │ │ │ │ │ { │ │ │ │ │ │ 'partID': 'contacts', │ │ │ │ │ │ 'partType': 'tables', │ │ │ │ │ │ 'version1Location': 'tables', │ │ │ │ │ │ 'version1Table': 'Contact' │ │ │ │ │ } │ │ │ │ ] │ │ │ } │ │ } │ } }
The meta
field for version 1 validation schemas for this rule should
include the rows for version 2 along with the version1Location
,
version1Table
, and version1Variable
column.