Skip to content

Script to convert UN codelist to pvmap#2092

Open
ajaits wants to merge 17 commits into
datacommonsorg:masterfrom
ajaits:pr-refactor-codelist-map
Open

Script to convert UN codelist to pvmap#2092
ajaits wants to merge 17 commits into
datacommonsorg:masterfrom
ajaits:pr-refactor-codelist-map

Conversation

@ajaits

@ajaits ajaits commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Script to convert UN codelists into PV maps. The pvmap is used to:

  • generate schema with a tmcf file and dc-import tool.
  • process into statvars using stat_var_processor

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces scripts, templates, and schemas to automate UN codelist mappings and generate statistical variable (statvar) groups, names, and DCIDs, alongside integrating a custom statvar DCID generator into the importer. The review feedback highlights a few high-to-medium severity issues: a typo and malformed regex pattern in clean_value_str, a logically inverted condition in statvar_dcid_gen.py that could lead to an AttributeError, a duplicate dictionary key in config_flags.py, and an unused variable add_prop in statvar_dcid_gen.py.

Comment thread scripts/un/codes/generate_codelist_map.py
Comment thread tools/statvar_importer/schema/statvar_dcid_gen.py
Comment thread tools/statvar_importer/config_flags.py
Comment thread tools/statvar_importer/schema/statvar_dcid_gen.py
Comment thread tools/statvar_importer/config_flags.py
Comment thread scripts/un/codes/generate_codelist_map.py
Comment thread scripts/un/codes/generate_codelist_map.py Outdated
Comment on lines +14 to +21
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(_SCRIPT_DIR)
sys.path.append(os.path.dirname(_SCRIPT_DIR))
sys.path.append(os.path.dirname(os.path.dirname(_SCRIPT_DIR)))
_DATA_DIR = os.path.dirname(os.path.dirname(os.path.dirname(_SCRIPT_DIR)))
sys.path.append(_DATA_DIR)
sys.path.append(os.path.join(_DATA_DIR, 'util'))
sys.path.append(os.path.join(_DATA_DIR, 'tools', 'statvar_importer'))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't smell right. If we have an anticipated file structure, should we take the root as an argument rather than trying to navigate around relative paths?

Ok to punt for a future revision, I could imagine this being prone to access issues when in a containerized runtime

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use this pattern in the data repo so that py scripts can be invoked from current folder or any other folder with relative paths.

I agree, it is seems like a hack and open to suggestion to preserve the flexibility to invoke a py script from any folder.

Comment on lines +99 to +100
if abs(number) > max_int:
# Convert very large ints to float with potential loss of precision

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we discussed with Luis implicitly converting some numbers to floats / doubles? I know we called out some instances where it was seen but I don't recall him saying it was ok to lower the precision.

I'm worried about this being a side effect and don't think we can unknowingly convert some numbers on behalf of a data custodian without their knowledge + consent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is required until the rest of the ingestion tools can handle large ints as it blocks the whole import now.
Yes this is a pending open item to fix all through the pipeline.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

max_int is a configurable value for python scripts. Currently set to sys.maxsize by default until downstream tools can support numbers as strings, after which it can be set much higher.

Comment on lines +11 to +19
_SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(_SCRIPT_DIR)
sys.path.append(os.path.dirname(_SCRIPT_DIR))
sys.path.append(os.path.dirname(os.path.dirname(_SCRIPT_DIR)))
_DATA_DIR = os.path.dirname(os.path.dirname(os.path.dirname(_SCRIPT_DIR)))
sys.path.append(_DATA_DIR)
sys.path.append(os.path.join(_DATA_DIR, 'util'))
sys.path.append(os.path.join(_DATA_DIR, 'tools', 'statvar_importer'))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous comment. This doesn't feel right for path traversal

Comment thread tools/statvar_importer/schema/statvar_dcid_gen.py
Comment on lines +57 to +58
"""Returns a property for the concept."""
c = eval_functions.str_to_camel_case(concept.lower().replace('_', ' '))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remind me of docs we have to clarify the intended name shapes?

This feels fragile as str_to_camel_case allows for the persistence of underscores. But here we strip them to spaces; which will then be preserved as spaces. But then we have code samples with again strip the underscores.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://schema.org/docs/styleguide.html says property names should be lowerCamelCase.
The conversion to space is to capitalize the following letter. Both space and _ are eventually removed.


def to_dcid(code: str) -> str:
"""Replace any non alphanumeric characters with '_'"""
value = re.sub(r'[^A-Za-z0-9\.]+', '_', code)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: if we're going to replace unmatched characters with '_', should we allow the underscore within the match to avoid needless character swaps?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to replace a sequence of __ with a single underscore.

Comment thread scripts/un/codes/generate_codelist_map.py Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants