This points to a validation requirement as well as a storage-type question.
@wastewater_belgium, reading the parts CSV as character data would preserve what contributors entered, including NA and values with leading zeros. That is useful at import. We should also retain the meaning of each field: an order value should still be checked as an integer when it applies, and a length limit should be checked as a non-negative integer or an explicitly supported instruction.
We already have missingness parts and sets for this. NA means not applicable, nr means not reported, and other codes distinguish reasons such as data not collected or withheld. A field’s missingnessSet identifies its allowed set. For example, nrNAMissingnessSet contains only nr and NA; the general set is broader. Validation should use the set assigned to that field, rather than accepting every missingness code everywhere.
This also connects to the country-code collision discussion. I proposed checking that a field’s ordinary values and its missingness set do not overlap. NA can otherwise mean either Namibia or not applicable. That check needs an explicit case policy too: nr and NR are different strings unless a consumer treats them as equivalent.
That gives us three things to keep aligned:
- The literal value stored in the dictionary CSV
- The field’s datatype, constraints and permitted missingness set
- The conversion used when generating a particular SQL representation
There is a definition gap to resolve for the dictionary itself. In the versions reviewed, addressesOrder, minLength and maxLength contain literal NA values, while their definitions have missingnessSet = NA instead of naming an allowed set. We should make the intended permission explicit. Broadening these fields to unrestricted text would leave that validation question unanswered.
For SQL, converting distinct reasons to NULL loses information. The literal ODM code null is also different from database NULL or an empty CSV cell. Where a numeric SQL column is needed, we should document the conversion and preserve the reason separately if the distinction must survive export.
Similarly, seeUnitVal is a reference to another constraint. Accepting arbitrary text would not check whether that reference can be resolved or whether the resulting bound is valid.
The LinkML generator already attempts to combine a field’s ordinary range with its selected missingness set. We need to test that both remain valid, that codes outside the selected set fail, and that unexplained blanks and unit-based bounds are handled explicitly.
Would those distinctions meet your database needs? An example where an SQL import must preserve “not applicable” separately from missing would help us test the approach.T