model2data 1.16.2__tar.gz → 1.16.3__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.
- model2data-1.16.3/PKG-INFO +406 -0
- model2data-1.16.3/README.md +389 -0
- model2data-1.16.3/README_PYPI.md +359 -0
- model2data-1.16.3/model2data.egg-info/PKG-INFO +406 -0
- {model2data-1.16.2 → model2data-1.16.3}/pyproject.toml +1 -1
- model2data-1.16.2/PKG-INFO +0 -354
- model2data-1.16.2/README.md +0 -449
- model2data-1.16.2/README_PYPI.md +0 -307
- model2data-1.16.2/model2data.egg-info/PKG-INFO +0 -354
- {model2data-1.16.2 → model2data-1.16.3}/LICENSE +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/LICENSE +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/VENDORED.md +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/base.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/column.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/enum.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/expression.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/index.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/note.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/project.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/reference.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/sticky_note.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/table.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/_classes/table_group.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/classes/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/constants.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/database.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/column.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/common.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/enum.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/generic.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/index.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/project.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/records.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/reference.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/sticky_note.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/table.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/table_group.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/definitions/table_partial.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/exceptions.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/parser/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/parser/blueprints.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/parser/parser.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/base.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/column.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/enum.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/expression.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/index.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/note.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/project.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/reference.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/renderer.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/sticky_note.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/table.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/table_group.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/dbml/default/utils.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/column.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/enum.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/expression.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/index.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/note.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/reference.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/renderer.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/table.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/renderer/sql/default/utils.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/_vendor/pydbml/tools.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/cli.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/hint_tests.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/naming.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/project.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/templates/dbt_project.yml.jinja +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/templates/hint_macros/model2data_hint_tests.sql +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/templates/hint_macros/model2data_parent_tests.sql +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/templates/hint_macros/model2data_when_tests.sql +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/templates/history_macros/model2data_history_tests.sql +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/templates/macros/generate_schema_name.sql +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/templates/profiles.yml.jinja +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/dbt/tests.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/defects/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/defects/apply.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/defects/checks.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/defects/presets.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/defects/report.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/core.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/days.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/faker.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/hints.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/history.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/kinds.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/options.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/parents.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/relationships.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/timeline.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/generate/when.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/guide/setup.md +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/guide/triage.md +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/guide/tune.md +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/check.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/columns.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/dbt.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/expression.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/graph.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/infer.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/lightdash.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/ossie.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/reader.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/semantic.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/sql.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/types.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/metrics/values.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/_yaml.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/dbml.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/document.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/dump.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/engine.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/errors.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/reader.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/types.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/model/validate.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/output.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/parse/__init__.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/parse/dbml.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/spec/PUBLISHING.md +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/spec/README.md +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/spec/examples/coffee_webshop.metrics.yml +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/spec/examples/coffee_webshop.model2data.yml +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/spec/metrics/README.md +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/spec/metrics/metrics.schema.json +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/spec/model.schema.json +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data/utils.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data.egg-info/SOURCES.txt +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data.egg-info/dependency_links.txt +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data.egg-info/entry_points.txt +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data.egg-info/requires.txt +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/model2data.egg-info/top_level.txt +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/setup.cfg +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_as_of_anchor.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_cli.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_cli_model.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_column_time_hints.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_coverage_gaps.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_days.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_dbml_parser.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_dbml_parser_fuzz.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_dbt_integration.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_dbt_naming.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_dbt_project.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_dbt_tests.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_defects.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_defects_dbt.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_defects_replay.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_defects_report.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_defects_review.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_determinism.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_distributions.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_examples_model.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_faker_name_inference.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_fast_paths.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_generation.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_guide.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_hint_tests.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_history.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_issue_lines.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_lone_country.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_cli.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_dbt.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_expression.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_lightdash.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_ossie.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_reader.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_semantic.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_spec.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_metrics_values.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_model.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_model_dbml.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_model_edges.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_model_messages.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_model_vocabulary.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_options.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_parent_dates.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_release_stress.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_reproducibility.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_row_identity.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_shaping.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_spec_alignment.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_spec_schema.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_table_seeds.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_timeline.py +0 -0
- {model2data-1.16.2 → model2data-1.16.3}/tests/test_when.py +0 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: model2data
|
|
3
|
+
Version: 1.16.3
|
|
4
|
+
Summary: Turn a data model into realistic synthetic data, a runnable dbt project and metrics with known values
|
|
5
|
+
Author: JB Analytica
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/JB-Analytica/model2data
|
|
8
|
+
Project-URL: Studio, https://studio.jbanalytica.com
|
|
9
|
+
Project-URL: Repository, https://github.com/JB-Analytica/model2data
|
|
10
|
+
Project-URL: Issues, https://github.com/JB-Analytica/model2data/issues
|
|
11
|
+
Project-URL: Changelog, https://github.com/JB-Analytica/model2data/blob/main/CHANGELOG.md
|
|
12
|
+
Keywords: dbt,dbml,synthetic-data,test-data,analytics-engineering,data-engineering,duckdb,seed-data
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Database
|
|
23
|
+
Classifier: Topic :: Software Development :: Testing
|
|
24
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: dbt-core>=1.11
|
|
29
|
+
Requires-Dist: dbt-duckdb>=1.11
|
|
30
|
+
Requires-Dist: faker>=37.12.0
|
|
31
|
+
Requires-Dist: jsonschema>=4.18
|
|
32
|
+
Requires-Dist: pandas>=2.3.3
|
|
33
|
+
Requires-Dist: pyparsing<4,>=3.1
|
|
34
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
35
|
+
Requires-Dist: typer>=0.20.0
|
|
36
|
+
Provides-Extra: postgres
|
|
37
|
+
Requires-Dist: dbt-postgres>=1.11; extra == "postgres"
|
|
38
|
+
Provides-Extra: dev
|
|
39
|
+
Requires-Dist: pytest; extra == "dev"
|
|
40
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
41
|
+
Requires-Dist: pre-commit; extra == "dev"
|
|
42
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
43
|
+
Requires-Dist: ty>=0.0.4; extra == "dev"
|
|
44
|
+
Requires-Dist: types-pyyaml; extra == "dev"
|
|
45
|
+
Requires-Dist: poethepoet>=0.38.0; extra == "dev"
|
|
46
|
+
Dynamic: license-file
|
|
47
|
+
|
|
48
|
+
# model2data
|
|
49
|
+
|
|
50
|
+
[](https://pypi.org/project/model2data/)
|
|
51
|
+
[](https://pypi.org/project/model2data/)
|
|
52
|
+
[](https://pypi.org/project/model2data/)
|
|
53
|
+
[](https://github.com/JB-Analytica/model2data/actions/workflows/ci.yml)
|
|
54
|
+
[](https://codecov.io/gh/JB-Analytica/model2data)
|
|
55
|
+
[](https://github.com/JB-Analytica/model2data/blob/main/LICENSE)
|
|
56
|
+
|
|
57
|
+
**Realistic, test-passing data for any data model, and the dbt project around it, in one command.**
|
|
58
|
+
|
|
59
|
+
You describe the tables. model2data generates data whose foreign keys resolve, whose dates make
|
|
60
|
+
sense and whose revenue adds up to a number it tells you in advance, and it writes a dbt project
|
|
61
|
+
that loads, builds and tests that data with one `dbt build`. No production access, no
|
|
62
|
+
hand-made CSVs, no dbt boilerplate.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
pip install model2data
|
|
66
|
+
model2data --file examples/ecommerce.model2data.yml --rows 200 --seed 42 # examples/ is in the GitHub repository
|
|
67
|
+
cd dbt_ecommerce && dbt build # PASS=59 ERROR=0
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
> **Rather design the model than type it?** [**model2data studio**](https://studio.jbanalytica.com)
|
|
73
|
+
> is this engine in the browser: draw the schema, see every column's values before you generate,
|
|
74
|
+
> shape the data on a sample of your own, and export a dbt project with a star schema or Data
|
|
75
|
+
> Vault on top. [Start free, no install →](https://studio.jbanalytica.com)
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## The problem
|
|
80
|
+
|
|
81
|
+
Every data project starts the same way: the model is ready and the data isn't.
|
|
82
|
+
|
|
83
|
+
- **Production data is off-limits.** Privacy, a pending contract, a source system nobody has
|
|
84
|
+
access to yet. The pipeline waits; the client demo waits.
|
|
85
|
+
- **Hand-made mock data breaks on contact.** Two CSVs are fine. Ten tables later, orders point at
|
|
86
|
+
customers who don't exist, shipments leave before they are ordered, and every `relationships`
|
|
87
|
+
test fails for reasons that have nothing to do with your SQL.
|
|
88
|
+
- **Random data proves nothing.** A dashboard over `Lorem ipsum` and uniform noise can't tell you
|
|
89
|
+
whether revenue is right, because nobody knows what revenue *should* be.
|
|
90
|
+
- **Fixtures rot.** A CSV committed once is right the day it was exported; after that it drifts
|
|
91
|
+
from the model, and CI tests against the past.
|
|
92
|
+
|
|
93
|
+
So teams spend days on throwaway data, or ship pipelines tested against nothing.
|
|
94
|
+
|
|
95
|
+
## The solution
|
|
96
|
+
|
|
97
|
+
Write the model once. model2data reads it and produces data that behaves like the real thing, and
|
|
98
|
+
the dbt project to prove it:
|
|
99
|
+
|
|
100
|
+
| You need | model2data gives you |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| Data that looks real | `email` gets emails, `city` gets cities, `sku ean13` gets barcodes: about 40 name patterns and every Faker provider, in any locale. |
|
|
103
|
+
| Joins that work | Tables generated in dependency order; every foreign key hits a row that exists. An order never predates its customer (`after: customers.created_at`). |
|
|
104
|
+
| A project, not a pile of files | Seeds, staging models, `not_null`/`unique`/`relationships`/`accepted_values` tests and a DuckDB or Postgres profile. `dbt build` goes green. |
|
|
105
|
+
| Numbers you can check | A metrics file defines revenue once; the run writes its exact value per month and a dbt test that the warehouse must reproduce. |
|
|
106
|
+
| Fixtures you can commit | Same model, seed and `--as-of`: the same bytes, on any machine, any day. |
|
|
107
|
+
| Data that fails on purpose | `--defects training` breaks each standard dbt test once and writes down which. |
|
|
108
|
+
|
|
109
|
+
Nothing but a schema goes in; nothing but synthetic data comes out. It is MIT licensed and runs
|
|
110
|
+
anywhere Python 3.10 to 3.14 does.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Before and after
|
|
115
|
+
|
|
116
|
+
In: a model (here the `orders` table of
|
|
117
|
+
[`examples/ecommerce.model2data.yml`](https://github.com/JB-Analytica/model2data/blob/main/examples/ecommerce.model2data.yml)) and, optionally, the
|
|
118
|
+
metrics that matter ([`examples/ecommerce.metrics.yml`](https://github.com/JB-Analytica/model2data/blob/main/examples/ecommerce.metrics.yml)). DBML,
|
|
119
|
+
hand-written or exported from an existing database, works as input too.
|
|
120
|
+
|
|
121
|
+
```yaml
|
|
122
|
+
orders:
|
|
123
|
+
columns:
|
|
124
|
+
id: {type: bigint, pk: true, not_null: true}
|
|
125
|
+
customer_id: {type: bigint, not_null: true, references: customers.id}
|
|
126
|
+
order_date: {type: timestamp, not_null: true}
|
|
127
|
+
total_amount:
|
|
128
|
+
type: numeric
|
|
129
|
+
not_null: true
|
|
130
|
+
generate: {min: 10, max: 5000}
|
|
131
|
+
status: order_status
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
metrics:
|
|
136
|
+
revenue:
|
|
137
|
+
measure: orders.total_amount
|
|
138
|
+
agg: sum
|
|
139
|
+
where:
|
|
140
|
+
orders.status: [processing, shipped, delivered]
|
|
141
|
+
time: orders.order_date
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
model2data --file examples/ecommerce.model2data.yml --metrics examples/ecommerce.metrics.yml \
|
|
146
|
+
--rows 200 --seed 42 --as-of 2026-01-31
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Out: a dbt project that runs.
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
dbt_ecommerce/
|
|
153
|
+
├── seeds/raw/ customers.csv, orders.csv, order_items.csv, products.csv, ...
|
|
154
|
+
├── models/staging/ stg_<table>.sql + stg_<table>.yml (with tests), for each table
|
|
155
|
+
├── data-tests/metrics/ one test per metric: the warehouse must match the known value
|
|
156
|
+
├── osi/ecommerce.yml the model and its metrics as Apache Ossie
|
|
157
|
+
├── metric_values.json each metric's known value, overall and per month
|
|
158
|
+
├── dbt_project.yml
|
|
159
|
+
└── profiles.yml DuckDB, zero config
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
Finished running 5 seeds, 49 data tests, 5 view models in 0 hours 0 minutes and 0.71 seconds (0.71s).
|
|
164
|
+
|
|
165
|
+
Done. PASS=59 WARN=0 ERROR=0 SKIP=0 NO-OP=0 REUSED=0 TOTAL=59
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
And `metric_values.json` says what a dashboard on this data must show: revenue 220,291.80 over
|
|
169
|
+
92 orders, month by month. If your semantic layer or BI tool says otherwise, the bug is in the
|
|
170
|
+
SQL, and you know it before a stakeholder does.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## Who it's for
|
|
175
|
+
|
|
176
|
+
- **Consultants who need a demo before source access.** Write the client's model after the
|
|
177
|
+
kick-off call, generate a year of their business, and show a working dbt project and dashboard
|
|
178
|
+
in week one, without touching production.
|
|
179
|
+
- **Analytics engineers who want real fixtures in CI.** Commit the model, generate with `--seed`
|
|
180
|
+
and `--as-of`, and every CI run builds against the same bytes. `--days` hands an incremental
|
|
181
|
+
model tomorrow's batch.
|
|
182
|
+
- **Trainers who need data that fails for the right reason.** `--defects training` makes
|
|
183
|
+
`unique`, `not_null`, `relationships` and `accepted_values` each fail once, and says where.
|
|
184
|
+
- **Teams who define metrics once.** Write revenue in one file, let `dbt build` prove the SQL,
|
|
185
|
+
and hand the definitions to Apache Ossie or Lightdash.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## model2data studio: design the model, ship the project
|
|
190
|
+
|
|
191
|
+
The CLI is the engine. [**model2data studio**](https://studio.jbanalytica.com) is where models get
|
|
192
|
+
designed, shown to a client and handed to a team, and it is built by the same people on the same
|
|
193
|
+
engine, so what you preview is byte for byte what you export.
|
|
194
|
+
|
|
195
|
+

|
|
196
|
+
|
|
197
|
+
What it adds to the CLI:
|
|
198
|
+
|
|
199
|
+
- **A live diagram as you type.** Write YAML or DBML (dbdiagram schemas work unchanged), or paste
|
|
200
|
+
SQL `CREATE TABLE` statements, and the entity diagram redraws as you type. Click a column to
|
|
201
|
+
see everything that joins to it. Drag a column onto another to draw the reference.
|
|
202
|
+
- **See the data before you generate it.** Every column shows an example of the value it will
|
|
203
|
+
get, and columns nothing recognises are flagged, so placeholder data never slips through.
|
|
204
|
+
- **Shape it like your data.** Drop in a CSV sample, or just summary statistics when even a sample
|
|
205
|
+
can't leave the warehouse, and the studio proposes ranges, distributions, null rates, enum
|
|
206
|
+
weights, seasonality and skew, each with a before-and-after chart. The file is profiled in your
|
|
207
|
+
browser and never uploaded.
|
|
208
|
+
- **More than staging.** Export the dbt project with a Kimball star schema, a Data Vault, or a
|
|
209
|
+
dbt semantic layer on top, real models with tests, derived from the same schema.
|
|
210
|
+
- **Regenerate in CI.** An API key, the `model2data-studio` CLI and an MCP server let a pipeline
|
|
211
|
+
or a coding agent pull fresh data from the saved project, so fixtures follow the model instead
|
|
212
|
+
of the last export.
|
|
213
|
+
- **Share it.** A read-only link that also embeds as a clean diagram in Notion, Confluence or a
|
|
214
|
+
wiki.
|
|
215
|
+
|
|
216
|
+
| | CLI (this repo) | Studio Free | Studio Pro |
|
|
217
|
+
| --- | --- | --- | --- |
|
|
218
|
+
| Engine: realistic, FK-correct, deterministic data | ✓ | ✓ | ✓ |
|
|
219
|
+
| Live diagram, value previews, model checks | | ✓ | ✓ |
|
|
220
|
+
| Rows per table | unlimited | 100 | 50,000 |
|
|
221
|
+
| Saved projects | | 2 | unlimited |
|
|
222
|
+
| Share links and embeds | | ✓ | ✓ |
|
|
223
|
+
| CSV export | ✓ | ✓ | ✓ |
|
|
224
|
+
| dbt project download | ✓ (staging) | preview | ✓ |
|
|
225
|
+
| Shape from a sample, visual shaping | | preview | ✓ |
|
|
226
|
+
| Star schema, Data Vault, semantic layer | | preview | ✓ |
|
|
227
|
+
| API keys, CI pulls, MCP server | | | ✓ |
|
|
228
|
+
|
|
229
|
+
**Pro is EUR 99 a month** (or EUR 990 a year); **Team is EUR 399 a month for five seats.**
|
|
230
|
+
For a consultant, that's less than an hour of the time it replaces on the first project.
|
|
231
|
+
|
|
232
|
+
**[Open the studio, free →](https://studio.jbanalytica.com)** ·
|
|
233
|
+
[Plans and pricing](https://www.jbanalytica.com/model2data/pricing/)
|
|
234
|
+
|
|
235
|
+
Keep using the CLI for scripting and committed fixtures; it stays free and open source. Use the
|
|
236
|
+
studio when the model is still being designed, when someone else needs to see it, or when the
|
|
237
|
+
project needs more than a staging layer.
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
## Everything the engine does
|
|
242
|
+
|
|
243
|
+
**Values that look real.** About 40 column-name patterns (`email`, `first_name`, `city`, `phone`,
|
|
244
|
+
`company`, ...), any Faker provider as a type (`billing_country state`, `sku ean13`), and
|
|
245
|
+
`--locale nl_BE` for people and addresses from one country. → [The model file](https://github.com/JB-Analytica/model2data/blob/main/docs/model-file.md)
|
|
246
|
+
|
|
247
|
+
**Foreign keys that resolve.** Every foreign key points at a parent row that exists, onto a
|
|
248
|
+
primary or a unique key; composite keys hold; `after: customers.created_at` keeps a child's date
|
|
249
|
+
after its parent's; a column that repeats a parent's value through a foreign key holds the right
|
|
250
|
+
parent's value. → [The model file](https://github.com/JB-Analytica/model2data/blob/main/docs/model-file.md)
|
|
251
|
+
|
|
252
|
+
**A dbt project that runs.** Seeds, staging models, schema tests, tests from the model's own hints,
|
|
253
|
+
optional unit test fixtures (`--unit-tests`), and a DuckDB or Postgres profile.
|
|
254
|
+
→ [The generated dbt project](https://github.com/JB-Analytica/model2data/blob/main/docs/dbt-project.md)
|
|
255
|
+
|
|
256
|
+
**The same files, byte for byte.** Same model, `--seed`, `--as-of` and options, same files, with
|
|
257
|
+
the same model2data version. `--table-seed orders=7` re-rolls one table and leaves the rest alone.
|
|
258
|
+
→ [The determinism promise](https://github.com/JB-Analytica/model2data/blob/main/docs/generating.md#the-determinism-promise)
|
|
259
|
+
|
|
260
|
+
**Days after the first.** `--days 7` or `--next` adds new rows and updates existing ones; enum
|
|
261
|
+
`transitions` move an order from `pending` to `shipped`; each day is a batch or a changelog.
|
|
262
|
+
→ [Days after the first](https://github.com/JB-Analytica/model2data/blob/main/docs/days.md)
|
|
263
|
+
|
|
264
|
+
**History tables.** `history: true` writes every version of every row with `valid_from`,
|
|
265
|
+
`valid_to` and `is_current`, an SCD type 2 source. → [History tables](https://github.com/JB-Analytica/model2data/blob/main/docs/history.md)
|
|
266
|
+
|
|
267
|
+
**When things happen.** `--business-hours`, `--growth` and `--seasonality` shape timestamps;
|
|
268
|
+
`updated_at` never precedes `created_at`; `when` fills `shipped_at` only on shipped orders.
|
|
269
|
+
→ [When things happen](https://github.com/JB-Analytica/model2data/blob/main/docs/time-shapes.md)
|
|
270
|
+
|
|
271
|
+
**How the data is spread.** `--skew` lets a few customers place most orders; `weights`,
|
|
272
|
+
`true_rate`, `null_rate`, `distinct` and normal, lognormal or exponential `distribution`s shape a
|
|
273
|
+
column. → [How the data is spread](https://github.com/JB-Analytica/model2data/blob/main/docs/distributions.md)
|
|
274
|
+
|
|
275
|
+
**Defects on purpose.** `--defects training` or `messy`, or a table's own list: duplicate keys,
|
|
276
|
+
orphans, nulls, invalid values, messy text, late-arriving rows. `EXPECTED_FAILURES.md` says what
|
|
277
|
+
should fail. → [Defects on purpose](https://github.com/JB-Analytica/model2data/blob/main/docs/defects.md)
|
|
278
|
+
|
|
279
|
+
**Metrics with known values.** Each metric's value in `metric_values.json`, a dbt test per metric,
|
|
280
|
+
an Apache Ossie semantic model, and with `--lightdash` the same metrics as Lightdash reads them.
|
|
281
|
+
→ [Metrics with known values](https://github.com/JB-Analytica/model2data/blob/main/docs/metrics.md)
|
|
282
|
+
|
|
283
|
+
**Validate in CI.** `model2data validate` prints GitHub annotations; `uses: JB-Analytica/model2data@v1`
|
|
284
|
+
fails a pull request that breaks a model. Pre-commit and GitLab CI too. → [Validate models in CI](https://github.com/JB-Analytica/model2data/blob/main/docs/ci.md)
|
|
285
|
+
|
|
286
|
+
**Use it from an agent.** `uvx model2data@latest guide` prints instructions written for a coding
|
|
287
|
+
agent; [LLMS.md](https://github.com/JB-Analytica/model2data/blob/main/LLMS.md) takes an LLM from a plain-English description to a running project.
|
|
288
|
+
→ [Agents and LLMs](https://github.com/JB-Analytica/model2data/blob/main/docs/agents.md)
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## How it works
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
model (.model2data.yml or DBML) + metrics file (optional)
|
|
296
|
+
-> read and validate -> generate -> scaffold the dbt project + compute each metric's known value
|
|
297
|
+
-> seeds, staging models and tests, metric tests, metric_values.json, osi/, profiles.yml
|
|
298
|
+
-> dbt build
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
1. **Read.** The model is checked against [the spec](https://github.com/JB-Analytica/model2data/blob/main/model2data/spec/README.md) (DBML is converted
|
|
302
|
+
to the same model first), and a metrics file against [its spec](https://github.com/JB-Analytica/model2data/blob/main/model2data/spec/metrics/README.md)
|
|
303
|
+
and the model. A model with errors is refused with every issue and where it is.
|
|
304
|
+
2. **Generate.** Typed generation for SQL types, then a Faker provider named as the type, then
|
|
305
|
+
name-aware inference; foreign keys resolve against parent rows already generated. The metrics
|
|
306
|
+
file is never read here, so the data is the same with or without it.
|
|
307
|
+
3. **Scaffold.** CSV seeds, staging models that `ref()` them, schema and hint tests, descriptions
|
|
308
|
+
from the model, and a DuckDB or Postgres profile.
|
|
309
|
+
4. **Compute metrics.** Each metric's known value, a dbt test that checks it, the Apache Ossie
|
|
310
|
+
file and, with `--lightdash`, Lightdash metrics in the staging YAML.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Installation
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
pip install model2data # DuckDB included
|
|
318
|
+
pip install "model2data[postgres]" # to target Postgres with --adapter postgres
|
|
319
|
+
uvx model2data --help # or run it without installing
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
Python 3.10 to 3.14. The examples used on this page are in [`examples/`](https://github.com/JB-Analytica/model2data/tree/main/examples/).
|
|
323
|
+
|
|
324
|
+
Or skip the install: [model2data studio](https://studio.jbanalytica.com) runs the same engine in
|
|
325
|
+
the browser.
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Documentation
|
|
330
|
+
|
|
331
|
+
- [The model file](https://github.com/JB-Analytica/model2data/blob/main/docs/model-file.md): `.model2data.yml`, DBML as input, `validate`, `convert`
|
|
332
|
+
- [Generating a project](https://github.com/JB-Analytica/model2data/blob/main/docs/generating.md): row counts, `--as-of`, the determinism promise, `--table-seed`, `--locale`
|
|
333
|
+
- [The generated dbt project](https://github.com/JB-Analytica/model2data/blob/main/docs/dbt-project.md): `dbt build`, Postgres, unit tests, hint tests, structure
|
|
334
|
+
- [Days after the first](https://github.com/JB-Analytica/model2data/blob/main/docs/days.md) and [history tables](https://github.com/JB-Analytica/model2data/blob/main/docs/history.md)
|
|
335
|
+
- [When things happen](https://github.com/JB-Analytica/model2data/blob/main/docs/time-shapes.md) and [how the data is spread](https://github.com/JB-Analytica/model2data/blob/main/docs/distributions.md)
|
|
336
|
+
- [Defects on purpose](https://github.com/JB-Analytica/model2data/blob/main/docs/defects.md)
|
|
337
|
+
- [Metrics with known values](https://github.com/JB-Analytica/model2data/blob/main/docs/metrics.md)
|
|
338
|
+
- [Validate models in CI](https://github.com/JB-Analytica/model2data/blob/main/docs/ci.md)
|
|
339
|
+
- [Agents and LLMs](https://github.com/JB-Analytica/model2data/blob/main/docs/agents.md), and [LLMS.md](https://github.com/JB-Analytica/model2data/blob/main/LLMS.md)
|
|
340
|
+
- The [model spec](https://github.com/JB-Analytica/model2data/blob/main/model2data/spec/README.md) and the [metrics spec](https://github.com/JB-Analytica/model2data/blob/main/model2data/spec/metrics/README.md)
|
|
341
|
+
- [Examples](https://github.com/JB-Analytica/model2data/blob/main/examples/README.md) and the [changelog](https://github.com/JB-Analytica/model2data/blob/main/CHANGELOG.md)
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## dbt-core versions
|
|
346
|
+
|
|
347
|
+
model2data requires **dbt-core >= 1.11**, tracking [dbt's own version support
|
|
348
|
+
policy](https://docs.getdbt.com/docs/dbt-versions): 1.11 is the oldest minor release dbt Labs
|
|
349
|
+
still supports. Generated projects build without deprecation warnings on every supported
|
|
350
|
+
version, and CI proves it on each push with a real `dbt build` against both the floor and the
|
|
351
|
+
newest release. Pinned to an older dbt-core? model2data 0.5.x supports down to 1.8.5.
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## Design decisions and limitations
|
|
356
|
+
|
|
357
|
+
- **DuckDB by default**, because it needs no setup. Postgres is supported with
|
|
358
|
+
`--adapter postgres`; other adapters need their profile adjusted by hand.
|
|
359
|
+
- **Deterministic synthetic data**, for testing, demos and prototyping. It is not a replacement
|
|
360
|
+
for real data, a migration tool or a real-time generator.
|
|
361
|
+
- **Metrics describe, never steer.** Adding or changing a metric changes no generated data, only
|
|
362
|
+
the known values and tests computed from it.
|
|
363
|
+
- **Generation is heuristic.** It looks real and keeps every key and rule the model states, but it
|
|
364
|
+
won't reproduce every quirk of a production distribution. (The studio's *Shape from a sample*
|
|
365
|
+
gets closer, from your own data's statistics.)
|
|
366
|
+
- **The generated project stops at staging.** Marts are yours to write, or the studio's Pro export
|
|
367
|
+
adds a star schema, Data Vault or semantic layer.
|
|
368
|
+
- **Composite foreign keys** are generated as independent single-column keys: each column is valid,
|
|
369
|
+
the combination only when the child declares it as a key (`keys`).
|
|
370
|
+
- A reference onto a column that is not a key is allowed with a warning; its values are drawn
|
|
371
|
+
from the ones the parent column holds.
|
|
372
|
+
|
|
373
|
+
---
|
|
374
|
+
|
|
375
|
+
## Project status
|
|
376
|
+
|
|
377
|
+
model2data is stable and actively developed, and follows semantic versioning. CI runs a real
|
|
378
|
+
`dbt build` against the oldest supported and the newest dbt-core on every push and checks the
|
|
379
|
+
output of a spread of models byte for byte. The [changelog](https://github.com/JB-Analytica/model2data/blob/main/CHANGELOG.md) names every release
|
|
380
|
+
that changes what a seed produces.
|
|
381
|
+
|
|
382
|
+
Open for contributions: more database adapters (Snowflake, BigQuery), and example mart-layer
|
|
383
|
+
models on top of staging.
|
|
384
|
+
|
|
385
|
+
## Contributing
|
|
386
|
+
|
|
387
|
+
Issues and pull requests are welcome: bugs, feature requests, example models, generators. See
|
|
388
|
+
[CONTRIBUTING.md](https://github.com/JB-Analytica/model2data/blob/main/CONTRIBUTING.md) for guidelines, [DEVELOPMENT.md](https://github.com/JB-Analytica/model2data/blob/main/DEVELOPMENT.md) for the local
|
|
389
|
+
setup and release process, and our [Code of Conduct](https://github.com/JB-Analytica/model2data/blob/main/CODE_OF_CONDUCT.md).
|
|
390
|
+
|
|
391
|
+
## License
|
|
392
|
+
|
|
393
|
+
MIT. See [LICENSE](https://github.com/JB-Analytica/model2data/blob/main/LICENSE).
|
|
394
|
+
|
|
395
|
+
---
|
|
396
|
+
|
|
397
|
+
<p align="center">
|
|
398
|
+
<a href="https://www.jbanalytica.com">
|
|
399
|
+
<img src="https://raw.githubusercontent.com/JB-Analytica/model2data/main/assets/jba-icon-dark-bg.svg" alt="JB Analytica" height="40">
|
|
400
|
+
</a>
|
|
401
|
+
<br>
|
|
402
|
+
Built and maintained by <a href="https://www.jbanalytica.com"><strong>JB Analytica</strong></a>:
|
|
403
|
+
Data & Analytics Engineering · Data Platform Architecture · Modern BI.
|
|
404
|
+
<br>
|
|
405
|
+
Designing a model? Try <a href="https://studio.jbanalytica.com"><strong>model2data studio</strong></a>, free in the browser.
|
|
406
|
+
</p>
|