datacontract-cli 0.12.1__tar.gz → 0.12.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.
- {datacontract_cli-0.12.1/datacontract_cli.egg-info → datacontract_cli-0.12.2}/PKG-INFO +31 -19
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/README.md +19 -7
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_changelog.py +2 -2
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/data_contract_checks.py +46 -15
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/check_soda_execute.py +13 -3
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/sql_type_converter.py +88 -26
- datacontract_cli-0.12.2/datacontract/imports/dbt_importer.py +366 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/protobuf_importer.py +56 -6
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/spark_importer.py +2 -2
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2/datacontract_cli.egg-info}/PKG-INFO +31 -19
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract_cli.egg-info/SOURCES.txt +1 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract_cli.egg-info/requires.txt +12 -12
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/pyproject.toml +27 -17
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_data_contract_checks.py +85 -1
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_dbt.py +1 -1
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_spark.py +54 -0
- datacontract_cli-0.12.2/tests/test_test_soda_connection_error.py +32 -0
- datacontract_cli-0.12.1/datacontract/imports/dbt_importer.py +0 -289
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/LICENSE +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/MANIFEST.in +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/__init__.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/api.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/catalog/catalog.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/changelog/__init__.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/changelog/changelog.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/changelog/normalize.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/cli.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_api.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_catalog.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_ci.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_export.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_import.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_init.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_lint.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_publish.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/command_test.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/data_contract.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/__init__.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/data_contract_test.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/__init__.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/athena.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/bigquery.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/databricks.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/duckdb_connection.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/impala.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/kafka.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/mysql.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/oracle.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/postgres.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/snowflake.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/sqlserver.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/connections/trino.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/__init__.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/avro_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/avro_idl_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/bigquery_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/custom_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/data_caterer_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/dbml_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/dbt_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/dcs_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/dqx_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/duckdb_type_converter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/excel_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/exporter_factory.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/go_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/great_expectations_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/html_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/iceberg_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/jsonschema_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/markdown_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/mermaid_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/odcs_export_helper.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/odcs_v3_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/pandas_type_converter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/protobuf_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/pydantic_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/rdf_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/sodacl_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/spark_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/sql_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/export/sqlalchemy_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/avro_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/bigquery_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/csv_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/dbml_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/dcs_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/excel_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/glue_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/iceberg_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/importer_factory.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/json_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/jsonschema_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/odcs_helper.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/odcs_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/parquet_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/sql_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/imports/unity_importer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/init/init_template.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/integration/entropy_data.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/lint/files.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/lint/resolve.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/lint/resources.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/lint/schema.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/lint/urls.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/model/changelog.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/model/exceptions.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/model/odcs.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/model/run.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/output/__init__.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/output/ci_output.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/output/json_test_results.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/output/junit_test_results.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/output/output_format.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/output/test_results_writer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/output/text_changelog_results.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/py.typed +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/odcs-3.1.0.init.yaml +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/datacontract.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/datacontract_odcs.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/index.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/datacontract_information.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/datacontract_terms.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/definition.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/example.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/model_field.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/quality.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/partials/server.html +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/templates/style/output.css +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract_cli.egg-info/dependency_links.txt +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract_cli.egg-info/entry_points.txt +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract_cli.egg-info/top_level.txt +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/setup.cfg +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_api.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_bigquery_soda_connection.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_catalog.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_changelog.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_changelog_engine.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_changelog_normalize.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_changelog_output_text.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_ci_output.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_cli.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_data_contract.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_data_contract_specification.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_description_linter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_download_datacontract_file.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_duckdb_json.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_avro.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_avro_idl.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_bigquery.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_complex_data_contract.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_custom.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_custom_exporter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_custom_model.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_data_caterer.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_dbml.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_dbt_models.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_dbt_sources.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_dbt_staging_sql.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_dqx.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_excel.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_go.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_great_expectations.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_html.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_iceberg.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_jsonschema.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_markdown.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_mermaid.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_odcs_v3.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_protobuf.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_pydantic.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_rdf.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_sodacl.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_spark.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_sql.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_sql_query.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_export_sqlalchemy.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_avro.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_bigquery.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_csv.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_dbml.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_excel.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_glue.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_iceberg.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_json.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_jsonschema.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_odcs_v3.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_parquet.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_protobuf.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_sql_oracle.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_sql_postgres.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_sql_snowflake.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_sql_sqlserver.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_import_unity_file.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_integration_entropydata.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_lint.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_require_env.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_resolve.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_roundtrip_jsonschema.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_sql_type_converter_physicaltype.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_sqlserver_soda_connection.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_api.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_athena_iceberg.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_azure_remote.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_bigquery.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_checks_filter.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_databricks.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_dataframe.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_delta.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_gcs_csv_remote.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_gcs_json_remote.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_kafka.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_kafka_remote.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_local_json.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_local_json_nd.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_mysql.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_oracle.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_output_json.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_output_junit.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_parquet.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_postgres.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_quality.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_s3_csv.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_s3_delta.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_s3_json.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_s3_json_complex.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_s3_json_multiple_models.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_s3_json_remote.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_schema_evolution.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_server_not_found.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_snowflake.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_sqlserver.py +0 -0
- {datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/tests/test_test_trino.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datacontract-cli
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.2
|
|
4
4
|
Summary: The datacontract CLI is an open source command-line tool for working with Data Contracts. It uses data contract YAML files to lint the data contract, connect to data sources and execute schema and quality tests, detect breaking changes, and export to different formats. The tool is written in Python. It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a Python library.
|
|
5
5
|
Author-email: Jochen Christ <jochen.christ@innoq.com>, Stefan Negele <stefan.negele@innoq.com>, Simon Harrer <simon.harrer@innoq.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,7 +11,7 @@ Classifier: Operating System :: OS Independent
|
|
|
11
11
|
Requires-Python: <3.13,>=3.10
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
13
|
License-File: LICENSE
|
|
14
|
-
Requires-Dist: typer<0.
|
|
14
|
+
Requires-Dist: typer<0.26,>=0.18.0
|
|
15
15
|
Requires-Dist: pydantic<2.14.0,>=2.8.2
|
|
16
16
|
Requires-Dist: pyyaml~=6.0.1
|
|
17
17
|
Requires-Dist: requests<2.34,>=2.31
|
|
@@ -21,7 +21,6 @@ Requires-Dist: pytz>=2024.1
|
|
|
21
21
|
Requires-Dist: python-multipart<1.0.0,>=0.0.20
|
|
22
22
|
Requires-Dist: rich<16.0,>=13.7
|
|
23
23
|
Requires-Dist: sqlglot<31.0.0,>=26.6.0
|
|
24
|
-
Requires-Dist: setuptools>=60
|
|
25
24
|
Requires-Dist: python-dotenv<2.0.0,>=1.0.0
|
|
26
25
|
Requires-Dist: boto3<2.0.0,>=1.34.41
|
|
27
26
|
Requires-Dist: Jinja2<4.0.0,>=3.1.5
|
|
@@ -29,6 +28,7 @@ Requires-Dist: jinja_partials<1.0.0,>=0.2.1
|
|
|
29
28
|
Requires-Dist: datacontract-specification<2.0.0,>=1.2.3
|
|
30
29
|
Requires-Dist: open-data-contract-standard<4.0.0,>=3.1.2
|
|
31
30
|
Requires-Dist: deepdiff<10.0.0,>=6.0.0
|
|
31
|
+
Requires-Dist: setuptools>=70
|
|
32
32
|
Provides-Extra: avro
|
|
33
33
|
Requires-Dist: avro==1.12.1; extra == "avro"
|
|
34
34
|
Provides-Extra: bigquery
|
|
@@ -41,7 +41,7 @@ Provides-Extra: databricks
|
|
|
41
41
|
Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "databricks"
|
|
42
42
|
Requires-Dist: soda-core-spark[databricks]<3.6.0,>=3.3.20; extra == "databricks"
|
|
43
43
|
Requires-Dist: databricks-sql-connector<4.3.0,>=3.7.0; extra == "databricks"
|
|
44
|
-
Requires-Dist: databricks-sdk<0.
|
|
44
|
+
Requires-Dist: databricks-sdk<0.106.0; extra == "databricks"
|
|
45
45
|
Requires-Dist: pyspark<5.0.0,>=3.5.0; extra == "databricks"
|
|
46
46
|
Provides-Extra: iceberg
|
|
47
47
|
Requires-Dist: pyiceberg==0.11.1; extra == "iceberg"
|
|
@@ -51,12 +51,12 @@ Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "kafka"
|
|
|
51
51
|
Requires-Dist: pyspark<5.0.0,>=3.5.0; extra == "kafka"
|
|
52
52
|
Provides-Extra: mysql
|
|
53
53
|
Requires-Dist: soda-core-mysql<3.6.0,>=3.3.20; extra == "mysql"
|
|
54
|
-
Requires-Dist: mysql-connector-python<
|
|
54
|
+
Requires-Dist: mysql-connector-python<9.7.0,>=8.0.30; extra == "mysql"
|
|
55
55
|
Provides-Extra: postgres
|
|
56
56
|
Requires-Dist: soda-core-postgres<3.6.0,>=3.3.20; extra == "postgres"
|
|
57
57
|
Provides-Extra: s3
|
|
58
58
|
Requires-Dist: s3fs<2027.0.0,>=2025.2.0; extra == "s3"
|
|
59
|
-
Requires-Dist: aiobotocore<3.
|
|
59
|
+
Requires-Dist: aiobotocore<3.6.0,>=2.17.0; extra == "s3"
|
|
60
60
|
Provides-Extra: snowflake
|
|
61
61
|
Requires-Dist: snowflake-connector-python[pandas]<4.5,>=3.6; extra == "snowflake"
|
|
62
62
|
Requires-Dist: soda-core-snowflake<3.6.0,>=3.3.20; extra == "snowflake"
|
|
@@ -68,8 +68,8 @@ Provides-Extra: athena
|
|
|
68
68
|
Requires-Dist: soda-core-athena<3.6.0,>=3.3.20; extra == "athena"
|
|
69
69
|
Provides-Extra: trino
|
|
70
70
|
Requires-Dist: soda-core-trino<3.6.0,>=3.3.20; extra == "trino"
|
|
71
|
-
Provides-Extra:
|
|
72
|
-
Requires-Dist:
|
|
71
|
+
Provides-Extra: impala
|
|
72
|
+
Requires-Dist: soda-core-impala<3.6.0,>=3.3.20; extra == "impala"
|
|
73
73
|
Provides-Extra: dbml
|
|
74
74
|
Requires-Dist: pydbml>=1.1.1; extra == "dbml"
|
|
75
75
|
Provides-Extra: duckdb
|
|
@@ -80,12 +80,12 @@ Requires-Dist: pyarrow>=18.1.0; extra == "parquet"
|
|
|
80
80
|
Provides-Extra: rdf
|
|
81
81
|
Requires-Dist: rdflib==7.6.0; extra == "rdf"
|
|
82
82
|
Provides-Extra: api
|
|
83
|
-
Requires-Dist: fastapi==0.136.
|
|
83
|
+
Requires-Dist: fastapi==0.136.1; extra == "api"
|
|
84
84
|
Requires-Dist: uvicorn==0.44.0; extra == "api"
|
|
85
85
|
Provides-Extra: protobuf
|
|
86
|
-
Requires-Dist:
|
|
86
|
+
Requires-Dist: protobuf<7.0,>=3.20; extra == "protobuf"
|
|
87
87
|
Provides-Extra: all
|
|
88
|
-
Requires-Dist: datacontract-cli[api,athena,bigquery,csv,databricks,dbml,
|
|
88
|
+
Requires-Dist: datacontract-cli[api,athena,bigquery,csv,databricks,dbml,duckdb,excel,iceberg,impala,kafka,mysql,oracle,parquet,postgres,protobuf,rdf,s3,snowflake,sqlserver,trino]; extra == "all"
|
|
89
89
|
Provides-Extra: dev
|
|
90
90
|
Requires-Dist: datacontract-cli[all]; extra == "dev"
|
|
91
91
|
Requires-Dist: httpx==0.28.1; extra == "dev"
|
|
@@ -97,7 +97,7 @@ Requires-Dist: pre-commit<4.6.0,>=3.7.1; extra == "dev"
|
|
|
97
97
|
Requires-Dist: pytest; extra == "dev"
|
|
98
98
|
Requires-Dist: pytest-xdist; extra == "dev"
|
|
99
99
|
Requires-Dist: pymssql==2.3.13; extra == "dev"
|
|
100
|
-
Requires-Dist: ruff==0.15.
|
|
100
|
+
Requires-Dist: ruff==0.15.12; extra == "dev"
|
|
101
101
|
Requires-Dist: testcontainers[kafka,minio,mssql,mysql,postgres]==4.14.2; extra == "dev"
|
|
102
102
|
Requires-Dist: trino==0.337.0; extra == "dev"
|
|
103
103
|
Dynamic: license-file
|
|
@@ -345,23 +345,25 @@ A list of available extras:
|
|
|
345
345
|
| Amazon Athena | `pip install datacontract-cli[athena]` |
|
|
346
346
|
| Avro Support | `pip install datacontract-cli[avro]` |
|
|
347
347
|
| Google BigQuery | `pip install datacontract-cli[bigquery]` |
|
|
348
|
+
| CSV | `pip install datacontract-cli[csv]` |
|
|
348
349
|
| Databricks Integration | `pip install datacontract-cli[databricks]` |
|
|
350
|
+
| DBML | `pip install datacontract-cli[dbml]` |
|
|
349
351
|
| DuckDB (local/S3/GCS/Azure file testing) | `pip install datacontract-cli[duckdb]` |
|
|
352
|
+
| Excel | `pip install datacontract-cli[excel]` |
|
|
350
353
|
| Iceberg | `pip install datacontract-cli[iceberg]` |
|
|
354
|
+
| Impala | `pip install datacontract-cli[impala]` |
|
|
351
355
|
| Kafka Integration | `pip install datacontract-cli[kafka]` |
|
|
352
356
|
| MySQL Integration | `pip install datacontract-cli[mysql]` |
|
|
357
|
+
| Oracle | `pip install datacontract-cli[oracle]` |
|
|
358
|
+
| Parquet | `pip install datacontract-cli[parquet]` |
|
|
353
359
|
| PostgreSQL Integration | `pip install datacontract-cli[postgres]` |
|
|
360
|
+
| protobuf | `pip install datacontract-cli[protobuf]` |
|
|
361
|
+
| RDF | `pip install datacontract-cli[rdf]` |
|
|
354
362
|
| S3 Integration | `pip install datacontract-cli[s3]` |
|
|
355
363
|
| Snowflake Integration | `pip install datacontract-cli[snowflake]` |
|
|
356
364
|
| Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
|
|
357
365
|
| Trino | `pip install datacontract-cli[trino]` |
|
|
358
|
-
| Impala | `pip install datacontract-cli[impala]` |
|
|
359
|
-
| dbt | `pip install datacontract-cli[dbt]` |
|
|
360
|
-
| DBML | `pip install datacontract-cli[dbml]` |
|
|
361
|
-
| Parquet | `pip install datacontract-cli[parquet]` |
|
|
362
|
-
| RDF | `pip install datacontract-cli[rdf]` |
|
|
363
366
|
| API (run as web server) | `pip install datacontract-cli[api]` |
|
|
364
|
-
| protobuf | `pip install datacontract-cli[protobuf]` |
|
|
365
367
|
|
|
366
368
|
|
|
367
369
|
## Documentation
|
|
@@ -1972,7 +1974,17 @@ datacontract import csv --source "test.csv"
|
|
|
1972
1974
|
<details markdown="1">
|
|
1973
1975
|
<summary><strong>protobuf</strong></summary>
|
|
1974
1976
|
|
|
1975
|
-
Importing from protobuf File. Specify file in `source` parameter.
|
|
1977
|
+
Importing from protobuf File. Specify file in `source` parameter.
|
|
1978
|
+
|
|
1979
|
+
Requires the `protoc` compiler installed on the system. Install with:
|
|
1980
|
+
|
|
1981
|
+
| Platform | Command |
|
|
1982
|
+
|----------------|--------------------------------------|
|
|
1983
|
+
| macOS | `brew install protobuf` |
|
|
1984
|
+
| Debian/Ubuntu | `sudo apt install protobuf-compiler` |
|
|
1985
|
+
| Fedora/RHEL | `sudo dnf install protobuf-compiler` |
|
|
1986
|
+
| Arch | `sudo pacman -S protobuf` |
|
|
1987
|
+
| Windows | `choco install protoc` (or [download a release](https://github.com/protocolbuffers/protobuf/releases)) |
|
|
1976
1988
|
|
|
1977
1989
|
Example:
|
|
1978
1990
|
|
|
@@ -241,23 +241,25 @@ A list of available extras:
|
|
|
241
241
|
| Amazon Athena | `pip install datacontract-cli[athena]` |
|
|
242
242
|
| Avro Support | `pip install datacontract-cli[avro]` |
|
|
243
243
|
| Google BigQuery | `pip install datacontract-cli[bigquery]` |
|
|
244
|
+
| CSV | `pip install datacontract-cli[csv]` |
|
|
244
245
|
| Databricks Integration | `pip install datacontract-cli[databricks]` |
|
|
246
|
+
| DBML | `pip install datacontract-cli[dbml]` |
|
|
245
247
|
| DuckDB (local/S3/GCS/Azure file testing) | `pip install datacontract-cli[duckdb]` |
|
|
248
|
+
| Excel | `pip install datacontract-cli[excel]` |
|
|
246
249
|
| Iceberg | `pip install datacontract-cli[iceberg]` |
|
|
250
|
+
| Impala | `pip install datacontract-cli[impala]` |
|
|
247
251
|
| Kafka Integration | `pip install datacontract-cli[kafka]` |
|
|
248
252
|
| MySQL Integration | `pip install datacontract-cli[mysql]` |
|
|
253
|
+
| Oracle | `pip install datacontract-cli[oracle]` |
|
|
254
|
+
| Parquet | `pip install datacontract-cli[parquet]` |
|
|
249
255
|
| PostgreSQL Integration | `pip install datacontract-cli[postgres]` |
|
|
256
|
+
| protobuf | `pip install datacontract-cli[protobuf]` |
|
|
257
|
+
| RDF | `pip install datacontract-cli[rdf]` |
|
|
250
258
|
| S3 Integration | `pip install datacontract-cli[s3]` |
|
|
251
259
|
| Snowflake Integration | `pip install datacontract-cli[snowflake]` |
|
|
252
260
|
| Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
|
|
253
261
|
| Trino | `pip install datacontract-cli[trino]` |
|
|
254
|
-
| Impala | `pip install datacontract-cli[impala]` |
|
|
255
|
-
| dbt | `pip install datacontract-cli[dbt]` |
|
|
256
|
-
| DBML | `pip install datacontract-cli[dbml]` |
|
|
257
|
-
| Parquet | `pip install datacontract-cli[parquet]` |
|
|
258
|
-
| RDF | `pip install datacontract-cli[rdf]` |
|
|
259
262
|
| API (run as web server) | `pip install datacontract-cli[api]` |
|
|
260
|
-
| protobuf | `pip install datacontract-cli[protobuf]` |
|
|
261
263
|
|
|
262
264
|
|
|
263
265
|
## Documentation
|
|
@@ -1868,7 +1870,17 @@ datacontract import csv --source "test.csv"
|
|
|
1868
1870
|
<details markdown="1">
|
|
1869
1871
|
<summary><strong>protobuf</strong></summary>
|
|
1870
1872
|
|
|
1871
|
-
Importing from protobuf File. Specify file in `source` parameter.
|
|
1873
|
+
Importing from protobuf File. Specify file in `source` parameter.
|
|
1874
|
+
|
|
1875
|
+
Requires the `protoc` compiler installed on the system. Install with:
|
|
1876
|
+
|
|
1877
|
+
| Platform | Command |
|
|
1878
|
+
|----------------|--------------------------------------|
|
|
1879
|
+
| macOS | `brew install protobuf` |
|
|
1880
|
+
| Debian/Ubuntu | `sudo apt install protobuf-compiler` |
|
|
1881
|
+
| Fedora/RHEL | `sudo dnf install protobuf-compiler` |
|
|
1882
|
+
| Arch | `sudo pacman -S protobuf` |
|
|
1883
|
+
| Windows | `choco install protoc` (or [download a release](https://github.com/protocolbuffers/protobuf/releases)) |
|
|
1872
1884
|
|
|
1873
1885
|
Example:
|
|
1874
1886
|
|
|
@@ -11,8 +11,8 @@ from datacontract.output.text_changelog_results import write_text_changelog_resu
|
|
|
11
11
|
epilog="Example: datacontract changelog datacontract-v1.yaml datacontract-v2.yaml",
|
|
12
12
|
)
|
|
13
13
|
def changelog(
|
|
14
|
-
v1: Annotated[str, typer.Argument(help="The location (path) of the source (before) data contract YAML.")],
|
|
15
|
-
v2: Annotated[str, typer.Argument(help="The location (path) of the target (after) data contract YAML.")],
|
|
14
|
+
v1: Annotated[str, typer.Argument(help="The location (url or path) of the source (before) data contract YAML.")],
|
|
15
|
+
v2: Annotated[str, typer.Argument(help="The location (url or path) of the target (after) data contract YAML.")],
|
|
16
16
|
debug: debug_option = None,
|
|
17
17
|
):
|
|
18
18
|
"""Show a changelog between two data contracts."""
|
{datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/data_contract_checks.py
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import re
|
|
2
3
|
import uuid
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from typing import List, Optional
|
|
5
|
-
from venv import logger
|
|
6
6
|
|
|
7
7
|
import yaml
|
|
8
8
|
from open_data_contract_standard.model import (
|
|
@@ -16,6 +16,8 @@ from open_data_contract_standard.model import (
|
|
|
16
16
|
from datacontract.export.sql_type_converter import convert_to_sql_type
|
|
17
17
|
from datacontract.model.run import Check
|
|
18
18
|
|
|
19
|
+
logger = logging.getLogger(__name__)
|
|
20
|
+
|
|
19
21
|
|
|
20
22
|
@dataclass
|
|
21
23
|
class QuotingConfig:
|
|
@@ -48,6 +50,28 @@ def _quote_field_name(field_name: str, quoting_config: QuotingConfig) -> str:
|
|
|
48
50
|
return field_name
|
|
49
51
|
|
|
50
52
|
|
|
53
|
+
_BACKTICK_DIALECTS = {"databricks", "bigquery", "mysql", "impala", "dataframe", "kafka"}
|
|
54
|
+
_ANSI_QUOTING_DIALECTS = {"postgres", "sqlserver", "snowflake", "azure", "s3", "gcs", "local"}
|
|
55
|
+
|
|
56
|
+
_BARE_IDENTIFIER_STRICT = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$")
|
|
57
|
+
_BARE_IDENTIFIER_PERMISSIVE = re.compile(r"^[A-Za-z_][A-Za-z0-9_$]*$")
|
|
58
|
+
_PERMISSIVE_BARE_DIALECTS = {"postgres", "snowflake", "oracle", "sqlserver"}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _quote_identifier_if_needed(identifier: str, server: Optional[Server]) -> str:
|
|
62
|
+
"""Quote an identifier only when the target dialect would reject it bare.
|
|
63
|
+
|
|
64
|
+
Avoids unnecessary quoting, because quoting leads to case-sensitivity.
|
|
65
|
+
"""
|
|
66
|
+
if identifier is None:
|
|
67
|
+
return identifier
|
|
68
|
+
server_type = server.type if server and server.type else None
|
|
69
|
+
pattern = _BARE_IDENTIFIER_PERMISSIVE if server_type in _PERMISSIVE_BARE_DIALECTS else _BARE_IDENTIFIER_STRICT
|
|
70
|
+
if pattern.match(identifier):
|
|
71
|
+
return identifier
|
|
72
|
+
return f"`{identifier}`" if server_type in _BACKTICK_DIALECTS else f'"{identifier}"'
|
|
73
|
+
|
|
74
|
+
|
|
51
75
|
def _get_logical_type_option(prop: SchemaProperty, key: str):
|
|
52
76
|
"""Get a logical type option value."""
|
|
53
77
|
if prop.logicalTypeOptions is None:
|
|
@@ -84,7 +108,7 @@ def create_checks(data_contract: OpenDataContractStandard, server: Server, schem
|
|
|
84
108
|
continue
|
|
85
109
|
schema_checks = to_schema_checks(schema_obj, server)
|
|
86
110
|
checks.extend(schema_checks)
|
|
87
|
-
checks.extend(to_servicelevel_checks(data_contract))
|
|
111
|
+
checks.extend(to_servicelevel_checks(data_contract, server))
|
|
88
112
|
return [check for check in checks if check is not None]
|
|
89
113
|
|
|
90
114
|
|
|
@@ -98,21 +122,21 @@ def to_schema_checks(schema_object: SchemaObject, server: Server) -> List[Check]
|
|
|
98
122
|
|
|
99
123
|
type1 = server.type if server and server.type else None
|
|
100
124
|
config = QuotingConfig(
|
|
101
|
-
quote_field_name=type1 in
|
|
102
|
-
quote_field_name_with_backticks=type1 in
|
|
103
|
-
quote_model_name=type1 in
|
|
104
|
-
quote_model_name_with_backticks=type1 in
|
|
125
|
+
quote_field_name=type1 in _ANSI_QUOTING_DIALECTS,
|
|
126
|
+
quote_field_name_with_backticks=type1 in _BACKTICK_DIALECTS,
|
|
127
|
+
quote_model_name=type1 in _ANSI_QUOTING_DIALECTS,
|
|
128
|
+
quote_model_name_with_backticks=type1 in _BACKTICK_DIALECTS,
|
|
105
129
|
)
|
|
106
130
|
quoting_config = config
|
|
107
131
|
|
|
108
132
|
for prop in properties:
|
|
109
133
|
property_name = prop.name
|
|
110
|
-
logical_type = prop.logicalType
|
|
111
134
|
|
|
112
135
|
checks.append(check_property_is_present(schema_name, property_name, quoting_config))
|
|
113
|
-
if check_types and
|
|
136
|
+
if check_types and (prop.physicalType is not None or prop.logicalType is not None):
|
|
114
137
|
sql_type: str = convert_to_sql_type(prop, server_type)
|
|
115
|
-
|
|
138
|
+
if sql_type is not None:
|
|
139
|
+
checks.append(check_property_type(schema_name, property_name, sql_type, quoting_config))
|
|
116
140
|
if prop.required:
|
|
117
141
|
checks.append(check_property_required(schema_name, property_name, quoting_config))
|
|
118
142
|
if prop.unique:
|
|
@@ -224,6 +248,9 @@ def check_property_is_present(model_name, field_name, quoting_config: QuotingCon
|
|
|
224
248
|
def check_property_type(
|
|
225
249
|
model_name: str, field_name: str, expected_type: str, quoting_config: QuotingConfig = QuotingConfig()
|
|
226
250
|
):
|
|
251
|
+
if expected_type is None:
|
|
252
|
+
logger.warning(f"Cannot build type check for {model_name}.{field_name}: expected_type is None.")
|
|
253
|
+
return None
|
|
227
254
|
check_type = "field_type"
|
|
228
255
|
check_key = f"{model_name}__{field_name}__{check_type}"
|
|
229
256
|
sodacl_check_dict = {
|
|
@@ -750,10 +777,10 @@ def check_quality_list(
|
|
|
750
777
|
elif quality.type == "sql":
|
|
751
778
|
if property_name is None:
|
|
752
779
|
check_key = f"{schema_name}__quality_sql_{count}"
|
|
753
|
-
check_type = "
|
|
780
|
+
check_type = "model_quality_sql"
|
|
754
781
|
else:
|
|
755
782
|
check_key = f"{schema_name}__{property_name}__quality_sql_{count}"
|
|
756
|
-
check_type = "
|
|
783
|
+
check_type = "field_quality_sql"
|
|
757
784
|
threshold = to_sodacl_threshold(quality)
|
|
758
785
|
query = prepare_query(quality, schema_name, property_name, quoting_config, server)
|
|
759
786
|
if query is None:
|
|
@@ -869,6 +896,7 @@ def prepare_query(
|
|
|
869
896
|
|
|
870
897
|
query = re.sub(r'["\']?\$?\{model}["\']?', model_name_for_soda, query)
|
|
871
898
|
query = re.sub(r'["\']?\$?\{table}["\']?', model_name_for_soda, query)
|
|
899
|
+
query = re.sub(r'["\']?\$?\{object}["\']?', model_name_for_soda, query)
|
|
872
900
|
|
|
873
901
|
if server and server.schema_:
|
|
874
902
|
if quoting_config.quote_model_name:
|
|
@@ -926,14 +954,14 @@ def _get_schema_by_name(data_contract: OpenDataContractStandard, name: str) -> O
|
|
|
926
954
|
return next((s for s in data_contract.schema_ if s.name == name), None)
|
|
927
955
|
|
|
928
956
|
|
|
929
|
-
def to_servicelevel_checks(data_contract: OpenDataContractStandard) -> List[Check]:
|
|
957
|
+
def to_servicelevel_checks(data_contract: OpenDataContractStandard, server: Optional[Server] = None) -> List[Check]:
|
|
930
958
|
checks: List[Check] = []
|
|
931
959
|
if data_contract.slaProperties is None:
|
|
932
960
|
return checks
|
|
933
961
|
|
|
934
962
|
for sla in data_contract.slaProperties:
|
|
935
963
|
if sla.property == "freshness":
|
|
936
|
-
check = to_sla_freshness_check(data_contract, sla)
|
|
964
|
+
check = to_sla_freshness_check(data_contract, sla, server)
|
|
937
965
|
if check is not None:
|
|
938
966
|
checks.append(check)
|
|
939
967
|
elif sla.property == "retention":
|
|
@@ -944,7 +972,9 @@ def to_servicelevel_checks(data_contract: OpenDataContractStandard) -> List[Chec
|
|
|
944
972
|
return checks
|
|
945
973
|
|
|
946
974
|
|
|
947
|
-
def to_sla_freshness_check(
|
|
975
|
+
def to_sla_freshness_check(
|
|
976
|
+
data_contract: OpenDataContractStandard, sla, server: Optional[Server] = None
|
|
977
|
+
) -> Check | None:
|
|
948
978
|
"""Create a freshness check from an ODCS latency SLA property."""
|
|
949
979
|
if sla.element is None:
|
|
950
980
|
logger.info("slaProperties.latency.element is not defined, skipping freshness check")
|
|
@@ -990,10 +1020,11 @@ def to_sla_freshness_check(data_contract: OpenDataContractStandard, sla) -> Chec
|
|
|
990
1020
|
|
|
991
1021
|
check_type = "servicelevel_freshness"
|
|
992
1022
|
check_key = "servicelevel_freshness"
|
|
1023
|
+
quoted_field = _quote_identifier_if_needed(field_name, server)
|
|
993
1024
|
sodacl_check_dict = {
|
|
994
1025
|
f"checks for {model_name}": [
|
|
995
1026
|
{
|
|
996
|
-
f"freshness({
|
|
1027
|
+
f"freshness({quoted_field}) < {threshold}": {
|
|
997
1028
|
"name": check_key,
|
|
998
1029
|
},
|
|
999
1030
|
}
|
{datacontract_cli-0.12.1 → datacontract_cli-0.12.2}/datacontract/engines/soda/check_soda_execute.py
RENAMED
|
@@ -191,13 +191,14 @@ def check_soda_execute(
|
|
|
191
191
|
)
|
|
192
192
|
|
|
193
193
|
if scan.has_error_logs():
|
|
194
|
-
|
|
194
|
+
reason = _first_error_message(scan_results) or "Engine soda-core has errors. See the logs for details."
|
|
195
|
+
run.log_error(f"Engine soda-core has errors: {reason}")
|
|
195
196
|
run.checks.append(
|
|
196
197
|
Check(
|
|
197
198
|
type="general",
|
|
198
199
|
name="Data Contract Tests",
|
|
199
|
-
result=ResultEnum.
|
|
200
|
-
reason=
|
|
200
|
+
result=ResultEnum.failed,
|
|
201
|
+
reason=reason,
|
|
201
202
|
engine="soda-core",
|
|
202
203
|
)
|
|
203
204
|
)
|
|
@@ -212,6 +213,15 @@ def get_check(run, scan_result) -> Check | None:
|
|
|
212
213
|
return None
|
|
213
214
|
|
|
214
215
|
|
|
216
|
+
def _first_error_message(scan_results: dict) -> str | None:
|
|
217
|
+
for log in scan_results.get("logs") or []:
|
|
218
|
+
if log.get("level") == "ERROR":
|
|
219
|
+
message = log.get("message")
|
|
220
|
+
if message:
|
|
221
|
+
return message.strip().splitlines()[0]
|
|
222
|
+
return None
|
|
223
|
+
|
|
224
|
+
|
|
215
225
|
def to_result(c) -> ResultEnum:
|
|
216
226
|
soda_outcome = c.get("outcome")
|
|
217
227
|
if soda_outcome == "pass":
|