exadata-validator 0.0.1__tar.gz → 1.2.0__tar.gz
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.
- exadata_validator-1.2.0/.gitignore +156 -0
- exadata_validator-1.2.0/AGENTS.md +47 -0
- {exadata_validator-0.0.1 → exadata_validator-1.2.0}/PKG-INFO +13 -16
- {exadata_validator-0.0.1 → exadata_validator-1.2.0}/README.md +8 -8
- exadata_validator-1.2.0/pyproject.toml +31 -0
- exadata_validator-1.2.0/tests/conftest.py +26 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_longitudinal_v_1_0/CDEsMetadata.json +45 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_longitudinal_v_1_0/dataset.csv +5 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/CDEsMetadata.json +88 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/column_not_present_in_cdes.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/dataset_exceeds_max.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/dataset_exceeds_min.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/dataset_is_not_unique.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/duplication_column_row_id.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/invalid_enum.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/invalid_type1.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/missing_column_dataset.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/missing_column_row_id.csv +6 -0
- exadata_validator-1.2.0/tests/data/fail/data_model_v_1_0/missing_column_subjectcode.csv +6 -0
- exadata_validator-1.2.0/tests/data/success/data_model1_v_1_0/CDEsMetadata.json +88 -0
- exadata_validator-1.2.0/tests/data/success/data_model1_v_1_0/dataset10.csv +6 -0
- exadata_validator-1.2.0/tests/data/success/data_model1_v_1_0/dataset20.csv +6 -0
- exadata_validator-1.2.0/tests/data/success/data_model_longitudinal_v_1_0/CDEsMetadata.json +45 -0
- exadata_validator-1.2.0/tests/data/success/data_model_longitudinal_v_1_0/dataset.csv +4 -0
- exadata_validator-1.2.0/tests/data/success/data_model_v_1_0/CDEsMetadata.json +90 -0
- exadata_validator-1.2.0/tests/data/success/data_model_v_1_0/dataset.csv +6 -0
- exadata_validator-1.2.0/tests/data/success/data_model_v_1_0/dataset1.csv +6 -0
- exadata_validator-1.2.0/tests/data/success/data_model_v_1_0/dataset10.csv +6 -0
- exadata_validator-1.2.0/tests/data/success/data_model_v_1_0/dataset123.csv +6 -0
- exadata_validator-1.2.0/tests/data/success/data_model_v_1_0/dataset2.csv +6 -0
- exadata_validator-1.2.0/tests/test_commands.py +158 -0
- exadata_validator-1.2.0/tests/test_dataelements.py +28 -0
- exadata_validator-1.2.0/tests/test_duckdb_validator.py +57 -0
- exadata_validator-1.2.0/uv.lock +147 -0
- exadata_validator-1.2.0/validator/__main__.py +4 -0
- {exadata_validator-0.0.1/data_validator → exadata_validator-1.2.0/validator}/commands.py +6 -6
- {exadata_validator-0.0.1/data_validator → exadata_validator-1.2.0/validator}/dataelements.py +2 -2
- {exadata_validator-0.0.1/data_validator → exadata_validator-1.2.0/validator}/duckdb_validator.py +9 -14
- {exadata_validator-0.0.1/data_validator → exadata_validator-1.2.0/validator}/reporting.py +0 -30
- {exadata_validator-0.0.1/data_validator → exadata_validator-1.2.0/validator}/usecases.py +10 -12
- exadata_validator-0.0.1/data_validator/__main__.py +0 -4
- exadata_validator-0.0.1/pyproject.toml +0 -27
- {exadata_validator-0.0.1/data_validator → exadata_validator-1.2.0/validator}/__init__.py +0 -0
- {exadata_validator-0.0.1/data_validator → exadata_validator-1.2.0/validator}/exceptions.py +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# Intelij
|
|
2
|
+
.idea/
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Byte-compiled / optimized / DLL files
|
|
6
|
+
__pycache__/
|
|
7
|
+
*.py[cod]
|
|
8
|
+
*$py.class
|
|
9
|
+
|
|
10
|
+
# C extensions
|
|
11
|
+
*.so
|
|
12
|
+
|
|
13
|
+
# Distribution / packaging
|
|
14
|
+
.Python
|
|
15
|
+
build/
|
|
16
|
+
develop-eggs/
|
|
17
|
+
dist/
|
|
18
|
+
downloads/
|
|
19
|
+
eggs/
|
|
20
|
+
.eggs/
|
|
21
|
+
lib/
|
|
22
|
+
lib64/
|
|
23
|
+
parts/
|
|
24
|
+
sdist/
|
|
25
|
+
var/
|
|
26
|
+
wheels/
|
|
27
|
+
pip-wheel-metadata/
|
|
28
|
+
share/python-wheels/
|
|
29
|
+
*.egg-info/
|
|
30
|
+
.installed.cfg
|
|
31
|
+
*.egg
|
|
32
|
+
MANIFEST
|
|
33
|
+
|
|
34
|
+
# PyInstaller
|
|
35
|
+
# Usually these files are written by a python script from a template
|
|
36
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
37
|
+
*.manifest
|
|
38
|
+
*.spec
|
|
39
|
+
|
|
40
|
+
# Installer logs
|
|
41
|
+
pip-log.txt
|
|
42
|
+
pip-delete-this-directory.txt
|
|
43
|
+
|
|
44
|
+
# Unit test / coverage reports
|
|
45
|
+
htmlcov/
|
|
46
|
+
.tox/
|
|
47
|
+
.nox/
|
|
48
|
+
.coverage
|
|
49
|
+
.coverage.*
|
|
50
|
+
.cache
|
|
51
|
+
nosetests.xml
|
|
52
|
+
coverage.xml
|
|
53
|
+
*.cover
|
|
54
|
+
*.py,cover
|
|
55
|
+
.hypothesis/
|
|
56
|
+
.pytest_cache/
|
|
57
|
+
|
|
58
|
+
# Translations
|
|
59
|
+
*.mo
|
|
60
|
+
*.pot
|
|
61
|
+
|
|
62
|
+
# Django stuff:
|
|
63
|
+
*.log
|
|
64
|
+
local_settings.py
|
|
65
|
+
db.sqlite3
|
|
66
|
+
db.sqlite3-journal
|
|
67
|
+
|
|
68
|
+
# Flask stuff:
|
|
69
|
+
instance/
|
|
70
|
+
.webassets-cache
|
|
71
|
+
|
|
72
|
+
# Scrapy stuff:
|
|
73
|
+
.scrapy
|
|
74
|
+
|
|
75
|
+
# Sphinx documentation
|
|
76
|
+
docs/_build/
|
|
77
|
+
|
|
78
|
+
# PyBuilder
|
|
79
|
+
target/
|
|
80
|
+
|
|
81
|
+
# Jupyter Notebook
|
|
82
|
+
.ipynb_checkpoints
|
|
83
|
+
|
|
84
|
+
# IPython
|
|
85
|
+
profile_default/
|
|
86
|
+
ipython_config.py
|
|
87
|
+
|
|
88
|
+
# pyenv
|
|
89
|
+
.python-version
|
|
90
|
+
|
|
91
|
+
# pipenv
|
|
92
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
93
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
94
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
95
|
+
# install all needed dependencies.
|
|
96
|
+
#Pipfile.lock
|
|
97
|
+
|
|
98
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
99
|
+
__pypackages__/
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
.env
|
|
106
|
+
.venv
|
|
107
|
+
env/
|
|
108
|
+
venv/
|
|
109
|
+
ENV/
|
|
110
|
+
env.bak/
|
|
111
|
+
venv.bak/
|
|
112
|
+
|
|
113
|
+
# Spyder project settings
|
|
114
|
+
.spyderproject
|
|
115
|
+
.spyproject
|
|
116
|
+
|
|
117
|
+
# Rope project settings
|
|
118
|
+
.ropeproject
|
|
119
|
+
|
|
120
|
+
# mkdocs documentation
|
|
121
|
+
/site
|
|
122
|
+
|
|
123
|
+
# mypy
|
|
124
|
+
.mypy_cache/
|
|
125
|
+
.dmypy.json
|
|
126
|
+
dmypy.json
|
|
127
|
+
|
|
128
|
+
# Pyre type checker
|
|
129
|
+
.pyre/
|
|
130
|
+
|
|
131
|
+
#temp files
|
|
132
|
+
*~
|
|
133
|
+
*.swp
|
|
134
|
+
*.swo
|
|
135
|
+
*#*
|
|
136
|
+
|
|
137
|
+
# vim stuff
|
|
138
|
+
.vim/
|
|
139
|
+
pyrightconfig.json
|
|
140
|
+
.vimspector.json
|
|
141
|
+
|
|
142
|
+
# macos
|
|
143
|
+
**/.DS_Store
|
|
144
|
+
|
|
145
|
+
# mip deployment config file
|
|
146
|
+
.deployment.toml
|
|
147
|
+
/configs
|
|
148
|
+
/smpc_configs
|
|
149
|
+
.stored_data/
|
|
150
|
+
*.db
|
|
151
|
+
/tests/test_data/.data_paths/
|
|
152
|
+
/tests/test_data/localworker*/
|
|
153
|
+
/logs/
|
|
154
|
+
|
|
155
|
+
# LLMs
|
|
156
|
+
.codex
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Agent Instructions: exadata-validator
|
|
2
|
+
|
|
3
|
+
This directory is a separate uv-managed package for validating data-model folders
|
|
4
|
+
using DuckDB. Follow the root `AGENTS.md` first, then these package-specific
|
|
5
|
+
rules.
|
|
6
|
+
|
|
7
|
+
## Package Overview
|
|
8
|
+
|
|
9
|
+
`exadata-validator` exposes a CLI through `validator.commands:entry` and can
|
|
10
|
+
also run as `python -m validator`.
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
Run commands from `exadata-validator/`.
|
|
15
|
+
|
|
16
|
+
Install:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
uv sync --all-groups
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Test:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uv run pytest -q
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Build:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
uv build
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Smoke test an installed package as CI does:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
python -m validator validate-data-model tests/data/success/data_model_longitudinal_v_1_0
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
|
|
42
|
+
- Keep dependency and lockfile changes local to this package unless the root
|
|
43
|
+
package also intentionally changes.
|
|
44
|
+
- Preserve the CLI contract documented in `README.md`.
|
|
45
|
+
- Add or update tests under `tests/` for validation behavior changes.
|
|
46
|
+
- Treat CSV/CDE validation semantics as public behavior for package users.
|
|
47
|
+
- Do not mix Exaflow service deployment concerns into this package.
|
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: exadata-validator
|
|
3
|
-
Version:
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Validate data-model folders using DuckDB.
|
|
5
5
|
Author: Exaflow Team
|
|
6
|
-
Requires-Python:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Requires-Dist: click (>=8.1,<8.2)
|
|
10
|
-
Requires-Dist: duckdb (>=1.1,<1.2)
|
|
6
|
+
Requires-Python: <3.11,>=3.10
|
|
7
|
+
Requires-Dist: click<8.2.0,>=8.1.0
|
|
8
|
+
Requires-Dist: duckdb<1.2.0,>=1.1.0
|
|
11
9
|
Description-Content-Type: text/markdown
|
|
12
10
|
|
|
13
11
|
# exadata-validator
|
|
14
12
|
|
|
15
13
|
`exadata-validator` validates data-model folders using DuckDB.
|
|
16
14
|
|
|
17
|
-
## Install
|
|
15
|
+
## Install with pip
|
|
18
16
|
|
|
19
17
|
```bash
|
|
20
18
|
python -m venv .venv
|
|
@@ -28,21 +26,21 @@ Validate a data model folder:
|
|
|
28
26
|
exadata-validator validate-data-model /path/to/data_model_folder
|
|
29
27
|
```
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
From the repository root:
|
|
29
|
+
Run as a Python module:
|
|
34
30
|
|
|
35
31
|
```bash
|
|
36
|
-
|
|
37
|
-
poetry install
|
|
32
|
+
python -m validator validate-data-model /path/to/data_model_folder
|
|
38
33
|
```
|
|
39
34
|
|
|
40
|
-
|
|
35
|
+
Useful options:
|
|
41
36
|
|
|
42
37
|
```bash
|
|
43
|
-
|
|
38
|
+
exadata-validator validate-data-model /path/to/data_model_folder --fail-fast
|
|
39
|
+
exadata-validator validate-data-model /path/to/data_model_folder --format html --output report.html
|
|
44
40
|
```
|
|
45
41
|
|
|
42
|
+
By default the command collects and reports all validation errors in text format. If `--format html` is used without `--output`, the report is written under `/tmp`.
|
|
43
|
+
|
|
46
44
|
Use `exadata-validator validate-data-model --help` for reporting, output, and threading options.
|
|
47
45
|
|
|
48
46
|
## Folder Layout
|
|
@@ -58,4 +56,3 @@ Use `exadata-validator validate-data-model --help` for reporting, output, and th
|
|
|
58
56
|
|
|
59
57
|
- CSV validation queries files directly with DuckDB and uses fused aggregate checks to reduce scan overhead.
|
|
60
58
|
- Folder-level dataset uniqueness is enforced across all CSV files via SQL using normalized codes (`trim + lower`).
|
|
61
|
-
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`exadata-validator` validates data-model folders using DuckDB.
|
|
4
4
|
|
|
5
|
-
## Install
|
|
5
|
+
## Install with pip
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
python -m venv .venv
|
|
@@ -16,21 +16,21 @@ Validate a data model folder:
|
|
|
16
16
|
exadata-validator validate-data-model /path/to/data_model_folder
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
From the repository root:
|
|
19
|
+
Run as a Python module:
|
|
22
20
|
|
|
23
21
|
```bash
|
|
24
|
-
|
|
25
|
-
poetry install
|
|
22
|
+
python -m validator validate-data-model /path/to/data_model_folder
|
|
26
23
|
```
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
Useful options:
|
|
29
26
|
|
|
30
27
|
```bash
|
|
31
|
-
|
|
28
|
+
exadata-validator validate-data-model /path/to/data_model_folder --fail-fast
|
|
29
|
+
exadata-validator validate-data-model /path/to/data_model_folder --format html --output report.html
|
|
32
30
|
```
|
|
33
31
|
|
|
32
|
+
By default the command collects and reports all validation errors in text format. If `--format html` is used without `--output`, the report is written under `/tmp`.
|
|
33
|
+
|
|
34
34
|
Use `exadata-validator validate-data-model --help` for reporting, output, and threading options.
|
|
35
35
|
|
|
36
36
|
## Folder Layout
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "exadata-validator"
|
|
3
|
+
version = "1.2.0"
|
|
4
|
+
description = "Validate data-model folders using DuckDB."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Exaflow Team" },
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.10,<3.11"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"click>=8.1.0,<8.2.0",
|
|
12
|
+
"duckdb>=1.1.0,<1.2.0",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.scripts]
|
|
16
|
+
exadata-validator = "validator.commands:entry"
|
|
17
|
+
|
|
18
|
+
[dependency-groups]
|
|
19
|
+
dev = [
|
|
20
|
+
"pytest>=8.4.0,<8.5.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[build-system]
|
|
24
|
+
requires = ["hatchling"]
|
|
25
|
+
build-backend = "hatchling.build"
|
|
26
|
+
|
|
27
|
+
[tool.hatch.build.targets.wheel]
|
|
28
|
+
packages = ["validator"]
|
|
29
|
+
|
|
30
|
+
[tool.pytest.ini_options]
|
|
31
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
TEST_DIR = Path(__file__).resolve().parent
|
|
7
|
+
DATA_DIR = TEST_DIR / "data"
|
|
8
|
+
|
|
9
|
+
SUCCESS_MODEL_DIR = DATA_DIR / "success" / "data_model_v_1_0"
|
|
10
|
+
FAIL_MODEL_DIR = DATA_DIR / "fail" / "data_model_v_1_0"
|
|
11
|
+
|
|
12
|
+
SUCCESS_METADATA_PATH = SUCCESS_MODEL_DIR / "CDEsMetadata.json"
|
|
13
|
+
FAIL_METADATA_PATH = FAIL_MODEL_DIR / "CDEsMetadata.json"
|
|
14
|
+
|
|
15
|
+
LONGITUDINAL_SUCCESS_DIR = DATA_DIR / "success" / "data_model_longitudinal_v_1_0"
|
|
16
|
+
LONGITUDINAL_FAIL_DIR = DATA_DIR / "fail" / "data_model_longitudinal_v_1_0"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def success_metadata():
|
|
21
|
+
return json.loads(SUCCESS_METADATA_PATH.read_text(encoding="utf-8"))
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.fixture
|
|
25
|
+
def fail_metadata():
|
|
26
|
+
return json.loads(FAIL_METADATA_PATH.read_text(encoding="utf-8"))
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"code": "data_model_longitudinal",
|
|
3
|
+
"label": "The Data Model Longitudinal",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"longitudinal": true,
|
|
6
|
+
"variables": [
|
|
7
|
+
{
|
|
8
|
+
"isCategorical": true,
|
|
9
|
+
"code": "dataset",
|
|
10
|
+
"sql_type": "text",
|
|
11
|
+
"description": "",
|
|
12
|
+
"enumerations": [
|
|
13
|
+
{"code": "dataset_longitudinal", "label": "Dataset Longitudinal"}
|
|
14
|
+
],
|
|
15
|
+
"label": "Dataset",
|
|
16
|
+
"methodology": "",
|
|
17
|
+
"type": "nominal"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"isCategorical": false,
|
|
21
|
+
"code": "subjectid",
|
|
22
|
+
"sql_type": "text",
|
|
23
|
+
"description": "",
|
|
24
|
+
"label": "subjectid",
|
|
25
|
+
"methodology": "",
|
|
26
|
+
"type": "nominal"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"isCategorical": true,
|
|
30
|
+
"label": "visitid",
|
|
31
|
+
"code": "visitid",
|
|
32
|
+
"sql_type": "text",
|
|
33
|
+
"enumerations": [
|
|
34
|
+
{"code": "BL", "label": "Base line"},
|
|
35
|
+
{"code": "FL1", "label": "Follow up 1"},
|
|
36
|
+
{"code": "FL2", "label": "Follow up 2"}
|
|
37
|
+
],
|
|
38
|
+
"description": "",
|
|
39
|
+
"methodology": "",
|
|
40
|
+
"type": "nominal"
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"groups": [
|
|
44
|
+
]
|
|
45
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"code": "data_model",
|
|
3
|
+
"label": "The Data Model",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"variables": [
|
|
6
|
+
{
|
|
7
|
+
"isCategorical": false,
|
|
8
|
+
"code": "var1",
|
|
9
|
+
"sql_type": "text",
|
|
10
|
+
"description": "",
|
|
11
|
+
"label": "Variable 1",
|
|
12
|
+
"methodology": "",
|
|
13
|
+
"type": "nominal"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"isCategorical": false,
|
|
17
|
+
"label": "subjectcode",
|
|
18
|
+
"code": "subjectcode",
|
|
19
|
+
"sql_type": "text",
|
|
20
|
+
"description": "",
|
|
21
|
+
"methodology": "",
|
|
22
|
+
"type": "nominal"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"isCategorical": true,
|
|
26
|
+
"code": "var2",
|
|
27
|
+
"sql_type": "text",
|
|
28
|
+
"description": "",
|
|
29
|
+
"enumerations": [
|
|
30
|
+
{"code": "l1", "label": "Level1"},
|
|
31
|
+
{"code": "l2", "label": "Level2"}
|
|
32
|
+
],
|
|
33
|
+
"label": "Variable 2",
|
|
34
|
+
"methodology": "",
|
|
35
|
+
"type": "nominal"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"isCategorical": true,
|
|
39
|
+
"code": "dataset",
|
|
40
|
+
"sql_type": "text",
|
|
41
|
+
"description": "",
|
|
42
|
+
"enumerations": [
|
|
43
|
+
{"code": "valid_dataset", "label": "Valid dataset"},
|
|
44
|
+
{"code": "dataset_is_not_unique", "label": "Dataset with more one value"}
|
|
45
|
+
],
|
|
46
|
+
"label": "Dataset",
|
|
47
|
+
"methodology": "",
|
|
48
|
+
"type": "nominal"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"groups": [
|
|
52
|
+
{
|
|
53
|
+
"name": "group",
|
|
54
|
+
"label": "The Group",
|
|
55
|
+
"variables": [
|
|
56
|
+
{
|
|
57
|
+
"isCategorical": false,
|
|
58
|
+
"code": "var3",
|
|
59
|
+
"sql_type": "real",
|
|
60
|
+
"minValue": 5,
|
|
61
|
+
"maxValue": 60,
|
|
62
|
+
"description": "",
|
|
63
|
+
"label": "Variable 3",
|
|
64
|
+
"methodology": "",
|
|
65
|
+
"type": "nominal"
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"groups": [
|
|
69
|
+
{
|
|
70
|
+
"name": "inner_group",
|
|
71
|
+
"label": "The Inner Group",
|
|
72
|
+
"variables": [
|
|
73
|
+
{
|
|
74
|
+
"isCategorical": false,
|
|
75
|
+
"code": "var4",
|
|
76
|
+
"sql_type": "int",
|
|
77
|
+
"units": "years",
|
|
78
|
+
"description": "",
|
|
79
|
+
"label": "Variable 4",
|
|
80
|
+
"methodology": "",
|
|
81
|
+
"type": "nominal"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"code": "data_model1",
|
|
3
|
+
"label": "The Data Model",
|
|
4
|
+
"version": "1.0",
|
|
5
|
+
"variables": [
|
|
6
|
+
{
|
|
7
|
+
"isCategorical": false,
|
|
8
|
+
"code": "var1",
|
|
9
|
+
"sql_type": "text",
|
|
10
|
+
"description": "",
|
|
11
|
+
"label": "Variable 1",
|
|
12
|
+
"methodology": "",
|
|
13
|
+
"type": "nominal"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"isCategorical": false,
|
|
17
|
+
"label": "subjectcode",
|
|
18
|
+
"code": "subjectcode",
|
|
19
|
+
"sql_type": "text",
|
|
20
|
+
"description": "",
|
|
21
|
+
"methodology": "",
|
|
22
|
+
"type": "nominal"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"isCategorical": true,
|
|
26
|
+
"code": "var2",
|
|
27
|
+
"sql_type": "text",
|
|
28
|
+
"description": "",
|
|
29
|
+
"enumerations": [
|
|
30
|
+
{"code": "l10", "label": "Level10"},
|
|
31
|
+
{"code": "l20", "label": "Level20"}
|
|
32
|
+
],
|
|
33
|
+
"label": "Variable 2",
|
|
34
|
+
"methodology": "",
|
|
35
|
+
"type": "nominal"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"isCategorical": true,
|
|
39
|
+
"code": "dataset",
|
|
40
|
+
"sql_type": "text",
|
|
41
|
+
"description": "",
|
|
42
|
+
"enumerations": [
|
|
43
|
+
{"code": "dataset10", "label": "Dataset 10"},
|
|
44
|
+
{"code": "dataset20", "label": "Dataset 20"}
|
|
45
|
+
],
|
|
46
|
+
"label": "Dataset",
|
|
47
|
+
"methodology": "",
|
|
48
|
+
"type": "nominal"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"groups": [
|
|
52
|
+
{
|
|
53
|
+
"name": "group",
|
|
54
|
+
"label": "The Group",
|
|
55
|
+
"variables": [
|
|
56
|
+
{
|
|
57
|
+
"isCategorical": false,
|
|
58
|
+
"code": "var3",
|
|
59
|
+
"sql_type": "real",
|
|
60
|
+
"minValue": 0,
|
|
61
|
+
"maxValue": 100,
|
|
62
|
+
"description": "",
|
|
63
|
+
"label": "Variable 3",
|
|
64
|
+
"methodology": "",
|
|
65
|
+
"type": "nominal"
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"groups": [
|
|
69
|
+
{
|
|
70
|
+
"name": "inner_group",
|
|
71
|
+
"label": "The Inner Group",
|
|
72
|
+
"variables": [
|
|
73
|
+
{
|
|
74
|
+
"isCategorical": false,
|
|
75
|
+
"code": "var4",
|
|
76
|
+
"sql_type": "int",
|
|
77
|
+
"units": "years",
|
|
78
|
+
"description": "",
|
|
79
|
+
"label": "Variable 4",
|
|
80
|
+
"methodology": "",
|
|
81
|
+
"type": "nominal"
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|