model2data 1.16.1__tar.gz → 1.16.2__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.1/model2data.egg-info → model2data-1.16.2}/PKG-INFO +1 -1
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/sql.py +24 -9
- {model2data-1.16.1 → model2data-1.16.2/model2data.egg-info}/PKG-INFO +1 -1
- {model2data-1.16.1 → model2data-1.16.2}/pyproject.toml +1 -1
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_values.py +15 -0
- {model2data-1.16.1 → model2data-1.16.2}/LICENSE +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/README.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/README_PYPI.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/LICENSE +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/VENDORED.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/base.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/column.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/enum.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/expression.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/index.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/note.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/project.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/reference.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/sticky_note.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/table.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/_classes/table_group.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/classes/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/constants.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/database.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/column.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/common.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/enum.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/generic.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/index.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/project.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/records.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/reference.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/sticky_note.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/table.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/table_group.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/table_partial.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/exceptions.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/parser/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/parser/blueprints.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/parser/parser.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/base.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/column.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/enum.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/expression.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/index.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/note.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/project.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/reference.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/renderer.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/sticky_note.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/table.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/table_group.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/utils.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/column.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/enum.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/expression.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/index.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/note.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/reference.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/renderer.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/table.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/utils.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/tools.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/cli.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/hint_tests.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/naming.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/project.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/dbt_project.yml.jinja +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/hint_macros/model2data_hint_tests.sql +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/hint_macros/model2data_parent_tests.sql +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/hint_macros/model2data_when_tests.sql +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/history_macros/model2data_history_tests.sql +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/macros/generate_schema_name.sql +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/profiles.yml.jinja +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/tests.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/defects/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/defects/apply.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/defects/checks.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/defects/presets.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/defects/report.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/core.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/days.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/faker.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/hints.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/history.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/kinds.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/options.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/parents.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/relationships.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/timeline.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/generate/when.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/guide/setup.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/guide/triage.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/guide/tune.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/check.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/columns.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/dbt.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/expression.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/graph.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/infer.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/lightdash.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/ossie.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/reader.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/semantic.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/types.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/metrics/values.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/_yaml.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/dbml.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/document.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/dump.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/engine.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/errors.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/reader.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/types.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/model/validate.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/output.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/parse/__init__.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/parse/dbml.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/spec/PUBLISHING.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/spec/README.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/spec/examples/coffee_webshop.metrics.yml +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/spec/examples/coffee_webshop.model2data.yml +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/spec/metrics/README.md +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/spec/metrics/metrics.schema.json +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/spec/model.schema.json +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data/utils.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data.egg-info/SOURCES.txt +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data.egg-info/dependency_links.txt +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data.egg-info/entry_points.txt +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data.egg-info/requires.txt +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/model2data.egg-info/top_level.txt +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/setup.cfg +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_as_of_anchor.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_cli.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_cli_model.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_column_time_hints.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_coverage_gaps.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_days.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_dbml_parser.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_dbml_parser_fuzz.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_dbt_integration.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_dbt_naming.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_dbt_project.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_dbt_tests.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_defects.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_defects_dbt.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_defects_replay.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_defects_report.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_defects_review.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_determinism.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_distributions.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_examples_model.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_faker_name_inference.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_fast_paths.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_generation.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_guide.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_hint_tests.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_history.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_issue_lines.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_lone_country.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_cli.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_dbt.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_expression.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_lightdash.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_ossie.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_reader.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_semantic.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_metrics_spec.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_model.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_model_dbml.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_model_edges.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_model_messages.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_model_vocabulary.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_options.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_parent_dates.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_release_stress.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_reproducibility.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_row_identity.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_shaping.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_spec_alignment.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_spec_schema.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_table_seeds.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_timeline.py +0 -0
- {model2data-1.16.1 → model2data-1.16.2}/tests/test_when.py +0 -0
|
@@ -5,11 +5,11 @@ Two dialects of the same thing:
|
|
|
5
5
|
- **warehouse SQL** (`query`, `scalar`), which the known values run on DuckDB
|
|
6
6
|
and the generated dbt tests run on DuckDB or Postgres. It reads relations a
|
|
7
7
|
caller names (a DuckDB table, a dbt `ref()`), joins the tables a metric's
|
|
8
|
-
filter and
|
|
9
|
-
whose parent is missing stays, and fails any filter on the
|
|
10
|
-
does), and casts every column it reads to the type its kind
|
|
11
|
-
(`model2data.metrics.columns.SQL_TYPES`), so the answer does not
|
|
12
|
-
how a CSV loader guessed the column's type.
|
|
8
|
+
filter is on (and, by month, its time) along their many-to-one path with
|
|
9
|
+
`left join` (a row whose parent is missing stays, and fails any filter on the
|
|
10
|
+
parent, as a null does), and casts every column it reads to the type its kind
|
|
11
|
+
is read as (`model2data.metrics.columns.SQL_TYPES`), so the answer does not
|
|
12
|
+
depend on how a CSV loader guessed the column's type.
|
|
13
13
|
- **ANSI SQL for Ossie** (`ansi`), over `dataset.field` names, with no joins:
|
|
14
14
|
an Ossie consumer joins along the relationships the document declares.
|
|
15
15
|
|
|
@@ -152,11 +152,15 @@ def aggregate_sql(
|
|
|
152
152
|
class _From:
|
|
153
153
|
"""The `from` and `join` clauses of a simple metric, and the alias of each table in them.
|
|
154
154
|
|
|
155
|
+
Joins only the tables in `needed` (of `metric.joins`, in its order): a table the
|
|
156
|
+
query reads no column of stays out, so a parent with a duplicated key cannot repeat
|
|
157
|
+
the metric's rows in a query that does not need it.
|
|
158
|
+
|
|
155
159
|
Every column the query reads is written by `column`, which also records it in `read`
|
|
156
160
|
(by table key), so `columns_read` knows them from the same code that writes them.
|
|
157
161
|
"""
|
|
158
162
|
|
|
159
|
-
def __init__(self, metric: ResolvedMetric, relation: Relation):
|
|
163
|
+
def __init__(self, metric: ResolvedMetric, relation: Relation, needed: set[str]):
|
|
160
164
|
assert metric.table is not None
|
|
161
165
|
self.lines = [f"from {relation(metric.table)} as t0"]
|
|
162
166
|
self.alias = {metric.table: "t0"}
|
|
@@ -164,6 +168,8 @@ class _From:
|
|
|
164
168
|
by_prefix: dict[tuple, str] = {(): "t0"}
|
|
165
169
|
table_of = {"t0": metric.table}
|
|
166
170
|
for table, path in metric.joins.items():
|
|
171
|
+
if table not in needed:
|
|
172
|
+
continue
|
|
167
173
|
for length in range(1, len(path) + 1):
|
|
168
174
|
prefix = path[:length]
|
|
169
175
|
if prefix in by_prefix:
|
|
@@ -194,9 +200,18 @@ class _From:
|
|
|
194
200
|
|
|
195
201
|
|
|
196
202
|
def _parts(
|
|
197
|
-
semantic: SemanticModel, metric: ResolvedMetric, relation: Relation
|
|
203
|
+
semantic: SemanticModel, metric: ResolvedMetric, relation: Relation, by_month: bool
|
|
198
204
|
) -> tuple[str, _From]:
|
|
199
|
-
|
|
205
|
+
# The total joins what its filter reads; by month, the time column's table as well.
|
|
206
|
+
needed = (
|
|
207
|
+
{condition.column.rpartition(".")[0] for condition in metric.where.conditions()}
|
|
208
|
+
if metric.where is not None
|
|
209
|
+
else set()
|
|
210
|
+
)
|
|
211
|
+
if by_month:
|
|
212
|
+
assert metric.time is not None
|
|
213
|
+
needed.add(metric.time.rpartition(".")[0])
|
|
214
|
+
clauses = _From(metric, relation, needed)
|
|
200
215
|
|
|
201
216
|
def column_of(path: str) -> tuple[str, ColumnKind]:
|
|
202
217
|
table, column = find_column(semantic.model, path)
|
|
@@ -217,7 +232,7 @@ def _query(
|
|
|
217
232
|
semantic: SemanticModel, name: str, relation: Relation, by_month: bool
|
|
218
233
|
) -> tuple[str, _From]:
|
|
219
234
|
metric = semantic.metrics[name]
|
|
220
|
-
aggregate, clauses = _parts(semantic, metric, relation)
|
|
235
|
+
aggregate, clauses = _parts(semantic, metric, relation, by_month)
|
|
221
236
|
joins = "\n".join(clauses.lines)
|
|
222
237
|
if not by_month:
|
|
223
238
|
return f"select {aggregate} as value\n{joins}", clauses
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "model2data"
|
|
7
|
-
version = "1.16.
|
|
7
|
+
version = "1.16.2"
|
|
8
8
|
description = "Turn a data model into realistic synthetic data, a runnable dbt project and metrics with known values"
|
|
9
9
|
readme = "README_PYPI.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -180,6 +180,21 @@ def test_a_metric_without_time_has_no_months(values):
|
|
|
180
180
|
assert values["with_undated"].by_month is None
|
|
181
181
|
|
|
182
182
|
|
|
183
|
+
def test_a_duplicated_parent_key_does_not_repeat_rows_in_a_total():
|
|
184
|
+
# Lines are dated by their order: the total joins no order, so a repeated order 1
|
|
185
|
+
# (as the `messy` defects preset repeats keys) cannot count lines 1 and 2 twice.
|
|
186
|
+
frames = _frames()
|
|
187
|
+
frames["orders"] = pd.concat([frames["orders"], frames["orders"].iloc[[0]]])
|
|
188
|
+
semantic = resolve(SHOP, load(METRICS, SHOP))
|
|
189
|
+
found = known_values(semantic, frames, seed=3, as_of="2025-03-01").values
|
|
190
|
+
assert found["lines_qty"].value == 11 # not 16, lines 1 and 2 again
|
|
191
|
+
assert found["lines_count"].value == 5
|
|
192
|
+
assert "join" not in query(semantic, "lines_qty", quote)
|
|
193
|
+
assert "join" in query(semantic, "lines_qty", quote, by_month=True)
|
|
194
|
+
# A filter on the order still needs it, and only it.
|
|
195
|
+
assert query(semantic, "paid_or_big", quote).count("left join") == 1
|
|
196
|
+
|
|
197
|
+
|
|
183
198
|
def test_the_json_is_stable_text():
|
|
184
199
|
metrics = load(
|
|
185
200
|
"model2data-metrics: 0.1.0\nmodel: shop\ninfer: false\nmetrics:\n"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/sticky_note.py
RENAMED
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/table_group.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/definitions/table_partial.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/__init__.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/column.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/enum.py
RENAMED
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/index.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/note.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/project.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/reference.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/renderer.py
RENAMED
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/table.py
RENAMED
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/dbml/default/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/__init__.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/column.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/enum.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/expression.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/index.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/note.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/reference.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/renderer.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/table.py
RENAMED
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/_vendor/pydbml/renderer/sql/default/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/dbt/templates/macros/generate_schema_name.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{model2data-1.16.1 → model2data-1.16.2}/model2data/spec/examples/coffee_webshop.model2data.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|