datacontract-cli 0.11.1__tar.gz → 0.11.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.
- {datacontract_cli-0.11.1/datacontract_cli.egg-info → datacontract_cli-0.11.3}/PKG-INFO +84 -50
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/README.md +70 -36
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/catalog/catalog.py +1 -1
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/cli.py +5 -5
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/data_contract_checks.py +1 -1
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/check_soda_execute.py +14 -1
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/duckdb_connection.py +70 -17
- datacontract_cli-0.11.3/datacontract/engines/soda/connections/impala.py +74 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/bigquery_exporter.py +2 -2
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/pydantic_exporter.py +15 -4
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/sql_type_converter.py +59 -1
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/init/init_template.py +1 -1
- datacontract_cli-0.11.3/datacontract/schemas/odcs-3.1.0.init.yaml +36 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3/datacontract_cli.egg-info}/PKG-INFO +84 -50
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/SOURCES.txt +3 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/requires.txt +13 -13
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/pyproject.toml +14 -14
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_download_datacontract_file.py +18 -3
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_pydantic.py +17 -1
- datacontract_cli-0.11.3/tests/test_test_schema_evolution.py +110 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/LICENSE +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/MANIFEST.in +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/__init__.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/api.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/data_contract.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/__init__.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/data_contract_test.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/__init__.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/athena.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/bigquery.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/databricks.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/kafka.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/oracle.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/postgres.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/snowflake.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/sqlserver.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/connections/trino.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/__init__.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/avro_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/avro_idl_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/custom_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/data_caterer_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/dbml_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/dbt_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/dcs_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/dqx_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/duckdb_type_converter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/excel_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/exporter_factory.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/go_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/great_expectations_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/html_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/iceberg_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/jsonschema_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/markdown_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/mermaid_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/odcs_export_helper.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/odcs_v3_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/pandas_type_converter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/protobuf_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/rdf_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/sodacl_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/spark_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/sql_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/export/sqlalchemy_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/avro_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/bigquery_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/csv_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/dbml_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/dbt_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/dcs_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/excel_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/glue_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/iceberg_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/importer_factory.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/json_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/jsonschema_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/odcs_helper.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/odcs_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/parquet_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/protobuf_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/spark_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/sql_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/imports/unity_importer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/integration/entropy_data.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/lint/files.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/lint/resolve.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/lint/resources.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/lint/schema.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/lint/urls.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/model/exceptions.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/model/odcs.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/model/run.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/output/__init__.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/output/junit_test_results.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/output/output_format.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/output/test_results_writer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/py.typed +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/datacontract.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/datacontract_odcs.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/index.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/datacontract_information.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/datacontract_terms.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/definition.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/example.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/model_field.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/quality.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/partials/server.html +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/templates/style/output.css +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/dependency_links.txt +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/entry_points.txt +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract_cli.egg-info/top_level.txt +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/setup.cfg +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_api.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_catalog.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_cli.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_data_contract_checks.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_data_contract_specification.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_description_linter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_duckdb_json.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_avro.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_avro_idl.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_bigquery.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_complex_data_contract.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_custom.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_custom_exporter.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_data_caterer.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_dbml.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_dbt_models.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_dbt_sources.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_dbt_staging_sql.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_dqx.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_excel.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_go.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_great_expectations.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_html.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_iceberg.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_jsonschema.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_markdown.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_mermaid.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_odcs_v3.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_protobuf.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_rdf.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_sodacl.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_spark.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_sql.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_sql_query.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_export_sqlalchemy.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_avro.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_bigquery.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_csv.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_dbml.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_dbt.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_excel.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_glue.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_iceberg.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_json.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_jsonschema.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_odcs_v3.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_parquet.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_protobuf.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_spark.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_sql_oracle.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_sql_postgres.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_sql_sqlserver.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_import_unity_file.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_integration_entropydata.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_lint.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_resolve.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_roundtrip_jsonschema.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_api.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_athena_iceberg.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_azure_remote.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_bigquery.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_databricks.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_dataframe.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_delta.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_gcs_csv_remote.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_gcs_json_remote.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_kafka.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_kafka_remote.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_local_json.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_local_json_nd.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_oracle.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_output_junit.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_parquet.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_postgres.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_quality.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_s3_csv.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_s3_delta.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_s3_json.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_s3_json_complex.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_s3_json_multiple_models.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_s3_json_remote.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_snowflake.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/tests/test_test_sqlserver.py +0 -0
- {datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/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.11.
|
|
3
|
+
Version: 0.11.3
|
|
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
|
|
@@ -16,12 +16,12 @@ Requires-Dist: pydantic<2.13.0,>=2.8.2
|
|
|
16
16
|
Requires-Dist: pyyaml~=6.0.1
|
|
17
17
|
Requires-Dist: requests<2.33,>=2.31
|
|
18
18
|
Requires-Dist: fastjsonschema<2.22.0,>=2.19.1
|
|
19
|
-
Requires-Dist: fastparquet<
|
|
19
|
+
Requires-Dist: fastparquet<2026.0.0,>=2024.5.0
|
|
20
20
|
Requires-Dist: numpy<2.0.0,>=1.26.4
|
|
21
21
|
Requires-Dist: python-multipart<1.0.0,>=0.0.20
|
|
22
22
|
Requires-Dist: rich<15.0,>=13.7
|
|
23
|
-
Requires-Dist: sqlglot<
|
|
24
|
-
Requires-Dist: duckdb<
|
|
23
|
+
Requires-Dist: sqlglot<29.0.0,>=26.6.0
|
|
24
|
+
Requires-Dist: duckdb<1.4.0,>=1.0.0
|
|
25
25
|
Requires-Dist: soda-core-duckdb<3.6.0,>=3.3.20
|
|
26
26
|
Requires-Dist: setuptools>=60
|
|
27
27
|
Requires-Dist: python-dotenv<2.0.0,>=1.0.0
|
|
@@ -29,7 +29,7 @@ Requires-Dist: boto3<2.0.0,>=1.34.41
|
|
|
29
29
|
Requires-Dist: Jinja2<4.0.0,>=3.1.5
|
|
30
30
|
Requires-Dist: jinja_partials<1.0.0,>=0.2.1
|
|
31
31
|
Requires-Dist: datacontract-specification<2.0.0,>=1.2.3
|
|
32
|
-
Requires-Dist: open-data-contract-standard<4.0.0,>=3.1.
|
|
32
|
+
Requires-Dist: open-data-contract-standard<4.0.0,>=3.1.2
|
|
33
33
|
Provides-Extra: avro
|
|
34
34
|
Requires-Dist: avro==1.12.1; extra == "avro"
|
|
35
35
|
Provides-Extra: bigquery
|
|
@@ -41,22 +41,22 @@ Requires-Dist: openpyxl<4.0.0,>=3.1.5; extra == "excel"
|
|
|
41
41
|
Provides-Extra: databricks
|
|
42
42
|
Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "databricks"
|
|
43
43
|
Requires-Dist: soda-core-spark[databricks]<3.6.0,>=3.3.20; extra == "databricks"
|
|
44
|
-
Requires-Dist: databricks-sql-connector<4.
|
|
44
|
+
Requires-Dist: databricks-sql-connector<4.3.0,>=3.7.0; extra == "databricks"
|
|
45
45
|
Requires-Dist: databricks-sdk<0.74.0; extra == "databricks"
|
|
46
|
-
Requires-Dist: pyspark<
|
|
46
|
+
Requires-Dist: pyspark<5.0.0,>=3.5.5; extra == "databricks"
|
|
47
47
|
Provides-Extra: iceberg
|
|
48
48
|
Requires-Dist: pyiceberg==0.10.0; extra == "iceberg"
|
|
49
49
|
Provides-Extra: kafka
|
|
50
50
|
Requires-Dist: datacontract-cli[avro]; extra == "kafka"
|
|
51
51
|
Requires-Dist: soda-core-spark-df<3.6.0,>=3.3.20; extra == "kafka"
|
|
52
|
-
Requires-Dist: pyspark<
|
|
52
|
+
Requires-Dist: pyspark<5.0.0,>=3.5.5; extra == "kafka"
|
|
53
53
|
Provides-Extra: postgres
|
|
54
54
|
Requires-Dist: soda-core-postgres<3.6.0,>=3.3.20; extra == "postgres"
|
|
55
55
|
Provides-Extra: s3
|
|
56
56
|
Requires-Dist: s3fs<2026.0.0,>=2025.2.0; extra == "s3"
|
|
57
|
-
Requires-Dist: aiobotocore<2.
|
|
57
|
+
Requires-Dist: aiobotocore<3.2.0,>=2.17.0; extra == "s3"
|
|
58
58
|
Provides-Extra: snowflake
|
|
59
|
-
Requires-Dist: snowflake-connector-python[pandas]<4.
|
|
59
|
+
Requires-Dist: snowflake-connector-python[pandas]<4.2,>=3.6; extra == "snowflake"
|
|
60
60
|
Requires-Dist: soda-core-snowflake<3.6.0,>=3.3.20; extra == "snowflake"
|
|
61
61
|
Provides-Extra: sqlserver
|
|
62
62
|
Requires-Dist: soda-core-sqlserver<3.6.0,>=3.3.20; extra == "sqlserver"
|
|
@@ -73,10 +73,10 @@ Requires-Dist: pydbml>=1.1.1; extra == "dbml"
|
|
|
73
73
|
Provides-Extra: parquet
|
|
74
74
|
Requires-Dist: pyarrow>=18.1.0; extra == "parquet"
|
|
75
75
|
Provides-Extra: rdf
|
|
76
|
-
Requires-Dist: rdflib==7.
|
|
76
|
+
Requires-Dist: rdflib==7.5.0; extra == "rdf"
|
|
77
77
|
Provides-Extra: api
|
|
78
78
|
Requires-Dist: fastapi==0.121.2; extra == "api"
|
|
79
|
-
Requires-Dist: uvicorn==0.
|
|
79
|
+
Requires-Dist: uvicorn==0.40.0; extra == "api"
|
|
80
80
|
Provides-Extra: protobuf
|
|
81
81
|
Requires-Dist: grpcio-tools>=1.53; extra == "protobuf"
|
|
82
82
|
Provides-Extra: all
|
|
@@ -86,9 +86,9 @@ Requires-Dist: datacontract-cli[all]; extra == "dev"
|
|
|
86
86
|
Requires-Dist: httpx==0.28.1; extra == "dev"
|
|
87
87
|
Requires-Dist: kafka-python; extra == "dev"
|
|
88
88
|
Requires-Dist: minio==7.2.17; extra == "dev"
|
|
89
|
-
Requires-Dist: moto==5.1.
|
|
89
|
+
Requires-Dist: moto==5.1.18; extra == "dev"
|
|
90
90
|
Requires-Dist: pandas>=2.1.0; extra == "dev"
|
|
91
|
-
Requires-Dist: pre-commit<4.
|
|
91
|
+
Requires-Dist: pre-commit<4.6.0,>=3.7.1; extra == "dev"
|
|
92
92
|
Requires-Dist: pytest; extra == "dev"
|
|
93
93
|
Requires-Dist: pytest-xdist; extra == "dev"
|
|
94
94
|
Requires-Dist: pymssql==2.3.9; extra == "dev"
|
|
@@ -120,7 +120,7 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
|
|
|
120
120
|
Let's look at this data contract:
|
|
121
121
|
[https://datacontract.com/orders-v1.odcs.yaml](https://datacontract.com/orders-v1.odcs.yaml)
|
|
122
122
|
|
|
123
|
-
We have a _servers_ section with endpoint details to a Postgres database, _schema_ for the structure and semantics of the data,
|
|
123
|
+
We have a _servers_ section with endpoint details to a Postgres database, _schema_ for the structure and semantics of the data, _service levels_ and _quality_ attributes that describe the expected freshness and number of rows.
|
|
124
124
|
|
|
125
125
|
This data contract contains all information to connect to the database and check that the actual data meets the defined schema specification and quality expectations.
|
|
126
126
|
We can use this information to test if the actual data product is compliant to the data contract.
|
|
@@ -342,6 +342,7 @@ A list of available extras:
|
|
|
342
342
|
| Snowflake Integration | `pip install datacontract-cli[snowflake]` |
|
|
343
343
|
| Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
|
|
344
344
|
| Trino | `pip install datacontract-cli[trino]` |
|
|
345
|
+
| Impala | `pip install datacontract-cli[impala]` |
|
|
345
346
|
| dbt | `pip install datacontract-cli[dbt]` |
|
|
346
347
|
| DBML | `pip install datacontract-cli[dbml]` |
|
|
347
348
|
| Parquet | `pip install datacontract-cli[parquet]` |
|
|
@@ -493,6 +494,7 @@ Supported server types:
|
|
|
493
494
|
- [kafka](#kafka)
|
|
494
495
|
- [postgres](#postgres)
|
|
495
496
|
- [trino](#trino)
|
|
497
|
+
- [impala](#impala)
|
|
496
498
|
- [api](#api)
|
|
497
499
|
- [local](#local)
|
|
498
500
|
|
|
@@ -655,8 +657,7 @@ datacontract.yaml
|
|
|
655
657
|
servers:
|
|
656
658
|
production:
|
|
657
659
|
type: azure
|
|
658
|
-
|
|
659
|
-
location: abfss://dataproducts/inventory_events/*.parquet
|
|
660
|
+
location: abfss://datameshdatabricksdemo.dfs.core.windows.net/inventory_events/*.parquet
|
|
660
661
|
format: parquet
|
|
661
662
|
```
|
|
662
663
|
|
|
@@ -1023,6 +1024,53 @@ models:
|
|
|
1023
1024
|
| `DATACONTRACT_TRINO_PASSWORD` | `mysecretpassword` | Password |
|
|
1024
1025
|
|
|
1025
1026
|
|
|
1027
|
+
#### Impala
|
|
1028
|
+
|
|
1029
|
+
Data Contract CLI can run Soda checks against an Apache Impala cluster.
|
|
1030
|
+
|
|
1031
|
+
##### Example
|
|
1032
|
+
|
|
1033
|
+
datacontract.yaml
|
|
1034
|
+
```yaml
|
|
1035
|
+
servers:
|
|
1036
|
+
impala:
|
|
1037
|
+
type: impala
|
|
1038
|
+
host: my-impala-host
|
|
1039
|
+
port: 443
|
|
1040
|
+
# Optional default database used for Soda scans
|
|
1041
|
+
database: my_database
|
|
1042
|
+
models:
|
|
1043
|
+
my_table_1: # corresponds to a table
|
|
1044
|
+
type: table
|
|
1045
|
+
# fields as usual …
|
|
1046
|
+
```
|
|
1047
|
+
|
|
1048
|
+
##### Environment Variables
|
|
1049
|
+
|
|
1050
|
+
| Environment Variable | Example | Description |
|
|
1051
|
+
|------------------------------- |-------------------- |------------- |
|
|
1052
|
+
| `DATACONTRACT_IMPALA_USERNAME` | `analytics_user` | Username used to connect to Impala |
|
|
1053
|
+
| `DATACONTRACT_IMPALA_PASSWORD` | `mysecretpassword` | Password for the Impala user |
|
|
1054
|
+
| `DATACONTRACT_IMPALA_USE_SSL` | `true` | Whether to use SSL; defaults to true if unset |
|
|
1055
|
+
| `DATACONTRACT_IMPALA_AUTH_MECHANISM` | `LDAP` | Authentication mechanism; defaults to LDAP |
|
|
1056
|
+
| `DATACONTRACT_IMPALA_USE_HTTP_TRANSPORT` | `true` | Whether to use the HTTP transport; defaults to true |
|
|
1057
|
+
| `DATACONTRACT_IMPALA_HTTP_PATH` | `cliservice` | HTTP path for the Impala service; defaults to cliservice |
|
|
1058
|
+
|
|
1059
|
+
### Type-mapping note (logicalType → Impala type)
|
|
1060
|
+
|
|
1061
|
+
If `physicalType` is not specified in the schema, we recommend the following mapping from `logicalType` to Impala column types:
|
|
1062
|
+
|
|
1063
|
+
|logicalType | Recommended Impala type |
|
|
1064
|
+
|------------|-------------------------|
|
|
1065
|
+
| `integer` | `INT` or `BIGINT` |
|
|
1066
|
+
| `number` | `DOUBLE`/`decimal(..)` |
|
|
1067
|
+
| `string` | `STRING` or `VARCHAR` |
|
|
1068
|
+
| `boolean` | `BOOLEAN` |
|
|
1069
|
+
| `date` | `DATE` |
|
|
1070
|
+
| `datetime` | `TIMESTAMP` |
|
|
1071
|
+
|
|
1072
|
+
This keeps the Impala schema compatible with the expectations of the Soda checks generated by datacontract-cli.
|
|
1073
|
+
|
|
1026
1074
|
#### API
|
|
1027
1075
|
|
|
1028
1076
|
Data Contract CLI can test APIs that return data in JSON format.
|
|
@@ -1569,38 +1617,25 @@ datacontract import --format sql --source my_ddl.sql --dialect postgres --output
|
|
|
1569
1617
|
|
|
1570
1618
|
Available import options:
|
|
1571
1619
|
|
|
1572
|
-
| Type | Description
|
|
1573
|
-
|
|
1574
|
-
| `avro` | Import from AVRO schemas
|
|
1575
|
-
| `bigquery` | Import from BigQuery Schemas
|
|
1576
|
-
| `csv` | Import from CSV File
|
|
1577
|
-
| `dbml` | Import from DBML models
|
|
1578
|
-
| `dbt` | Import from dbt models
|
|
1579
|
-
| `excel` | Import from ODCS Excel Template
|
|
1580
|
-
| `glue` | Import from AWS Glue DataCatalog
|
|
1581
|
-
| `iceberg` | Import from an Iceberg JSON Schema Definition
|
|
1582
|
-
| `jsonschema` | Import from JSON Schemas
|
|
1583
|
-
| `
|
|
1584
|
-
| `
|
|
1585
|
-
| `
|
|
1586
|
-
| `
|
|
1587
|
-
| `
|
|
1588
|
-
| `
|
|
1589
|
-
|
|
|
1590
|
-
| Missing something? | Please create an issue on GitHub | TBD |
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
#### ODCS
|
|
1594
|
-
|
|
1595
|
-
Import from Open Data Contract Standard (ODCS) v2 or v3.
|
|
1596
|
-
The importer automatically detects the ODCS version and imports the data contract.
|
|
1597
|
-
|
|
1598
|
-
Examples:
|
|
1620
|
+
| Type | Description | Status |
|
|
1621
|
+
|--------------------|-----------------------------------------------|---------|
|
|
1622
|
+
| `avro` | Import from AVRO schemas | ✅ |
|
|
1623
|
+
| `bigquery` | Import from BigQuery Schemas | ✅ |
|
|
1624
|
+
| `csv` | Import from CSV File | ✅ |
|
|
1625
|
+
| `dbml` | Import from DBML models | ✅ |
|
|
1626
|
+
| `dbt` | Import from dbt models | ✅ |
|
|
1627
|
+
| `excel` | Import from ODCS Excel Template | ✅ |
|
|
1628
|
+
| `glue` | Import from AWS Glue DataCatalog | ✅ |
|
|
1629
|
+
| `iceberg` | Import from an Iceberg JSON Schema Definition | partial |
|
|
1630
|
+
| `jsonschema` | Import from JSON Schemas | ✅ |
|
|
1631
|
+
| `parquet` | Import from Parquet File Metadata | ✅ |
|
|
1632
|
+
| `protobuf` | Import from Protobuf schemas | ✅ |
|
|
1633
|
+
| `spark` | Import from Spark StructTypes, Variant | ✅ |
|
|
1634
|
+
| `sql` | Import from SQL DDL | ✅ |
|
|
1635
|
+
| `unity` | Import from Databricks Unity Catalog | partial |
|
|
1636
|
+
| `excel` | Import from ODCS Excel Template | ✅ |
|
|
1637
|
+
| Missing something? | Please create an issue on GitHub | TBD |
|
|
1599
1638
|
|
|
1600
|
-
```bash
|
|
1601
|
-
# Example import from ODCS
|
|
1602
|
-
datacontract import --format odcs --source my_data_contract.odcs.yaml
|
|
1603
|
-
```
|
|
1604
1639
|
|
|
1605
1640
|
#### BigQuery
|
|
1606
1641
|
|
|
@@ -2202,8 +2237,7 @@ We are happy to receive your contributions. Propose your change in an issue or d
|
|
|
2202
2237
|
|
|
2203
2238
|
## Related Tools
|
|
2204
2239
|
|
|
2205
|
-
- [Data
|
|
2206
|
-
- [Data Contract GPT](https://gpt.datacontract.com) is a custom GPT that can help you write data contracts.
|
|
2240
|
+
- [Entropy Data](https://www.entropy-data.com/) is a commercial tool to manage data contracts. It contains a web UI, access management, and data governance for a data product marketplace based on data contracts.
|
|
2207
2241
|
- [Data Contract Editor](https://editor.datacontract.com) is an editor for Data Contracts, including a live html preview.
|
|
2208
2242
|
- [Data Contract Playground](https://data-catering.github.io/data-contract-playground/) allows you to validate and export your data contract to different formats within your browser.
|
|
2209
2243
|
|
|
@@ -21,7 +21,7 @@ It can be used as a standalone CLI tool, in a CI/CD pipeline, or directly as a P
|
|
|
21
21
|
Let's look at this data contract:
|
|
22
22
|
[https://datacontract.com/orders-v1.odcs.yaml](https://datacontract.com/orders-v1.odcs.yaml)
|
|
23
23
|
|
|
24
|
-
We have a _servers_ section with endpoint details to a Postgres database, _schema_ for the structure and semantics of the data,
|
|
24
|
+
We have a _servers_ section with endpoint details to a Postgres database, _schema_ for the structure and semantics of the data, _service levels_ and _quality_ attributes that describe the expected freshness and number of rows.
|
|
25
25
|
|
|
26
26
|
This data contract contains all information to connect to the database and check that the actual data meets the defined schema specification and quality expectations.
|
|
27
27
|
We can use this information to test if the actual data product is compliant to the data contract.
|
|
@@ -243,6 +243,7 @@ A list of available extras:
|
|
|
243
243
|
| Snowflake Integration | `pip install datacontract-cli[snowflake]` |
|
|
244
244
|
| Microsoft SQL Server | `pip install datacontract-cli[sqlserver]` |
|
|
245
245
|
| Trino | `pip install datacontract-cli[trino]` |
|
|
246
|
+
| Impala | `pip install datacontract-cli[impala]` |
|
|
246
247
|
| dbt | `pip install datacontract-cli[dbt]` |
|
|
247
248
|
| DBML | `pip install datacontract-cli[dbml]` |
|
|
248
249
|
| Parquet | `pip install datacontract-cli[parquet]` |
|
|
@@ -394,6 +395,7 @@ Supported server types:
|
|
|
394
395
|
- [kafka](#kafka)
|
|
395
396
|
- [postgres](#postgres)
|
|
396
397
|
- [trino](#trino)
|
|
398
|
+
- [impala](#impala)
|
|
397
399
|
- [api](#api)
|
|
398
400
|
- [local](#local)
|
|
399
401
|
|
|
@@ -556,8 +558,7 @@ datacontract.yaml
|
|
|
556
558
|
servers:
|
|
557
559
|
production:
|
|
558
560
|
type: azure
|
|
559
|
-
|
|
560
|
-
location: abfss://dataproducts/inventory_events/*.parquet
|
|
561
|
+
location: abfss://datameshdatabricksdemo.dfs.core.windows.net/inventory_events/*.parquet
|
|
561
562
|
format: parquet
|
|
562
563
|
```
|
|
563
564
|
|
|
@@ -924,6 +925,53 @@ models:
|
|
|
924
925
|
| `DATACONTRACT_TRINO_PASSWORD` | `mysecretpassword` | Password |
|
|
925
926
|
|
|
926
927
|
|
|
928
|
+
#### Impala
|
|
929
|
+
|
|
930
|
+
Data Contract CLI can run Soda checks against an Apache Impala cluster.
|
|
931
|
+
|
|
932
|
+
##### Example
|
|
933
|
+
|
|
934
|
+
datacontract.yaml
|
|
935
|
+
```yaml
|
|
936
|
+
servers:
|
|
937
|
+
impala:
|
|
938
|
+
type: impala
|
|
939
|
+
host: my-impala-host
|
|
940
|
+
port: 443
|
|
941
|
+
# Optional default database used for Soda scans
|
|
942
|
+
database: my_database
|
|
943
|
+
models:
|
|
944
|
+
my_table_1: # corresponds to a table
|
|
945
|
+
type: table
|
|
946
|
+
# fields as usual …
|
|
947
|
+
```
|
|
948
|
+
|
|
949
|
+
##### Environment Variables
|
|
950
|
+
|
|
951
|
+
| Environment Variable | Example | Description |
|
|
952
|
+
|------------------------------- |-------------------- |------------- |
|
|
953
|
+
| `DATACONTRACT_IMPALA_USERNAME` | `analytics_user` | Username used to connect to Impala |
|
|
954
|
+
| `DATACONTRACT_IMPALA_PASSWORD` | `mysecretpassword` | Password for the Impala user |
|
|
955
|
+
| `DATACONTRACT_IMPALA_USE_SSL` | `true` | Whether to use SSL; defaults to true if unset |
|
|
956
|
+
| `DATACONTRACT_IMPALA_AUTH_MECHANISM` | `LDAP` | Authentication mechanism; defaults to LDAP |
|
|
957
|
+
| `DATACONTRACT_IMPALA_USE_HTTP_TRANSPORT` | `true` | Whether to use the HTTP transport; defaults to true |
|
|
958
|
+
| `DATACONTRACT_IMPALA_HTTP_PATH` | `cliservice` | HTTP path for the Impala service; defaults to cliservice |
|
|
959
|
+
|
|
960
|
+
### Type-mapping note (logicalType → Impala type)
|
|
961
|
+
|
|
962
|
+
If `physicalType` is not specified in the schema, we recommend the following mapping from `logicalType` to Impala column types:
|
|
963
|
+
|
|
964
|
+
|logicalType | Recommended Impala type |
|
|
965
|
+
|------------|-------------------------|
|
|
966
|
+
| `integer` | `INT` or `BIGINT` |
|
|
967
|
+
| `number` | `DOUBLE`/`decimal(..)` |
|
|
968
|
+
| `string` | `STRING` or `VARCHAR` |
|
|
969
|
+
| `boolean` | `BOOLEAN` |
|
|
970
|
+
| `date` | `DATE` |
|
|
971
|
+
| `datetime` | `TIMESTAMP` |
|
|
972
|
+
|
|
973
|
+
This keeps the Impala schema compatible with the expectations of the Soda checks generated by datacontract-cli.
|
|
974
|
+
|
|
927
975
|
#### API
|
|
928
976
|
|
|
929
977
|
Data Contract CLI can test APIs that return data in JSON format.
|
|
@@ -1470,38 +1518,25 @@ datacontract import --format sql --source my_ddl.sql --dialect postgres --output
|
|
|
1470
1518
|
|
|
1471
1519
|
Available import options:
|
|
1472
1520
|
|
|
1473
|
-
| Type | Description
|
|
1474
|
-
|
|
1475
|
-
| `avro` | Import from AVRO schemas
|
|
1476
|
-
| `bigquery` | Import from BigQuery Schemas
|
|
1477
|
-
| `csv` | Import from CSV File
|
|
1478
|
-
| `dbml` | Import from DBML models
|
|
1479
|
-
| `dbt` | Import from dbt models
|
|
1480
|
-
| `excel` | Import from ODCS Excel Template
|
|
1481
|
-
| `glue` | Import from AWS Glue DataCatalog
|
|
1482
|
-
| `iceberg` | Import from an Iceberg JSON Schema Definition
|
|
1483
|
-
| `jsonschema` | Import from JSON Schemas
|
|
1484
|
-
| `
|
|
1485
|
-
| `
|
|
1486
|
-
| `
|
|
1487
|
-
| `
|
|
1488
|
-
| `
|
|
1489
|
-
| `
|
|
1490
|
-
|
|
|
1491
|
-
| Missing something? | Please create an issue on GitHub | TBD |
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
#### ODCS
|
|
1495
|
-
|
|
1496
|
-
Import from Open Data Contract Standard (ODCS) v2 or v3.
|
|
1497
|
-
The importer automatically detects the ODCS version and imports the data contract.
|
|
1498
|
-
|
|
1499
|
-
Examples:
|
|
1521
|
+
| Type | Description | Status |
|
|
1522
|
+
|--------------------|-----------------------------------------------|---------|
|
|
1523
|
+
| `avro` | Import from AVRO schemas | ✅ |
|
|
1524
|
+
| `bigquery` | Import from BigQuery Schemas | ✅ |
|
|
1525
|
+
| `csv` | Import from CSV File | ✅ |
|
|
1526
|
+
| `dbml` | Import from DBML models | ✅ |
|
|
1527
|
+
| `dbt` | Import from dbt models | ✅ |
|
|
1528
|
+
| `excel` | Import from ODCS Excel Template | ✅ |
|
|
1529
|
+
| `glue` | Import from AWS Glue DataCatalog | ✅ |
|
|
1530
|
+
| `iceberg` | Import from an Iceberg JSON Schema Definition | partial |
|
|
1531
|
+
| `jsonschema` | Import from JSON Schemas | ✅ |
|
|
1532
|
+
| `parquet` | Import from Parquet File Metadata | ✅ |
|
|
1533
|
+
| `protobuf` | Import from Protobuf schemas | ✅ |
|
|
1534
|
+
| `spark` | Import from Spark StructTypes, Variant | ✅ |
|
|
1535
|
+
| `sql` | Import from SQL DDL | ✅ |
|
|
1536
|
+
| `unity` | Import from Databricks Unity Catalog | partial |
|
|
1537
|
+
| `excel` | Import from ODCS Excel Template | ✅ |
|
|
1538
|
+
| Missing something? | Please create an issue on GitHub | TBD |
|
|
1500
1539
|
|
|
1501
|
-
```bash
|
|
1502
|
-
# Example import from ODCS
|
|
1503
|
-
datacontract import --format odcs --source my_data_contract.odcs.yaml
|
|
1504
|
-
```
|
|
1505
1540
|
|
|
1506
1541
|
#### BigQuery
|
|
1507
1542
|
|
|
@@ -2103,8 +2138,7 @@ We are happy to receive your contributions. Propose your change in an issue or d
|
|
|
2103
2138
|
|
|
2104
2139
|
## Related Tools
|
|
2105
2140
|
|
|
2106
|
-
- [Data
|
|
2107
|
-
- [Data Contract GPT](https://gpt.datacontract.com) is a custom GPT that can help you write data contracts.
|
|
2141
|
+
- [Entropy Data](https://www.entropy-data.com/) is a commercial tool to manage data contracts. It contains a web UI, access management, and data governance for a data product marketplace based on data contracts.
|
|
2108
2142
|
- [Data Contract Editor](https://editor.datacontract.com) is an editor for Data Contracts, including a live html preview.
|
|
2109
2143
|
- [Data Contract Playground](https://data-catering.github.io/data-contract-playground/) allows you to validate and export your data contract to different formats within your browser.
|
|
2110
2144
|
|
|
@@ -14,7 +14,7 @@ from datacontract.export.html_exporter import get_version
|
|
|
14
14
|
|
|
15
15
|
def _get_owner(odcs: OpenDataContractStandard) -> Optional[str]:
|
|
16
16
|
"""Get the owner from ODCS customProperties or team."""
|
|
17
|
-
if odcs.team and odcs.team.name:
|
|
17
|
+
if odcs.team and hasattr(odcs.team, "name") and odcs.team.name:
|
|
18
18
|
return odcs.team.name
|
|
19
19
|
if odcs.customProperties:
|
|
20
20
|
for prop in odcs.customProperties:
|
|
@@ -67,7 +67,7 @@ def common(
|
|
|
67
67
|
pass
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
@app.command()
|
|
70
|
+
@app.command(name="init")
|
|
71
71
|
def init(
|
|
72
72
|
location: Annotated[
|
|
73
73
|
str, typer.Argument(help="The location of the data contract file to create.")
|
|
@@ -90,7 +90,7 @@ def init(
|
|
|
90
90
|
console.print("📄 data contract written to " + location)
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
@app.command()
|
|
93
|
+
@app.command(name="lint")
|
|
94
94
|
def lint(
|
|
95
95
|
location: Annotated[
|
|
96
96
|
str,
|
|
@@ -125,7 +125,7 @@ def enable_debug_logging(debug: bool):
|
|
|
125
125
|
)
|
|
126
126
|
|
|
127
127
|
|
|
128
|
-
@app.command()
|
|
128
|
+
@app.command(name="test")
|
|
129
129
|
def test(
|
|
130
130
|
location: Annotated[
|
|
131
131
|
str,
|
|
@@ -187,7 +187,7 @@ def test(
|
|
|
187
187
|
write_test_result(run, console, output_format, output, data_contract)
|
|
188
188
|
|
|
189
189
|
|
|
190
|
-
@app.command()
|
|
190
|
+
@app.command(name="export")
|
|
191
191
|
def export(
|
|
192
192
|
format: Annotated[ExportFormat, typer.Option(help="The export format.")],
|
|
193
193
|
output: Annotated[
|
|
@@ -467,7 +467,7 @@ def _get_uvicorn_arguments(port: int, host: str, context: typer.Context) -> dict
|
|
|
467
467
|
return default_args | dict(zip(trimmed_keys, context.args[1::2]))
|
|
468
468
|
|
|
469
469
|
|
|
470
|
-
@app.command(context_settings={"allow_extra_args": True, "ignore_unknown_options": True})
|
|
470
|
+
@app.command(name="api", context_settings={"allow_extra_args": True, "ignore_unknown_options": True})
|
|
471
471
|
def api(
|
|
472
472
|
ctx: Annotated[typer.Context, typer.Option(help="Extra arguments to pass to uvicorn.run().")],
|
|
473
473
|
port: Annotated[int, typer.Option(help="Bind socket to this port.")] = 4242,
|
{datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/data_contract_checks.py
RENAMED
|
@@ -161,7 +161,7 @@ def to_schema_name(schema_object: SchemaObject, server_type: str) -> str:
|
|
|
161
161
|
# Use physicalName if set (ODCS standard way to specify actual table name)
|
|
162
162
|
if schema_object.physicalName:
|
|
163
163
|
return schema_object.physicalName
|
|
164
|
-
|
|
164
|
+
|
|
165
165
|
return schema_object.name
|
|
166
166
|
|
|
167
167
|
|
{datacontract_cli-0.11.1 → datacontract_cli-0.11.3}/datacontract/engines/soda/check_soda_execute.py
RENAMED
|
@@ -14,6 +14,7 @@ from open_data_contract_standard.model import OpenDataContractStandard, Server
|
|
|
14
14
|
from datacontract.engines.soda.connections.bigquery import to_bigquery_soda_configuration
|
|
15
15
|
from datacontract.engines.soda.connections.databricks import to_databricks_soda_configuration
|
|
16
16
|
from datacontract.engines.soda.connections.duckdb_connection import get_duckdb_connection
|
|
17
|
+
from datacontract.engines.soda.connections.impala import to_impala_soda_configuration
|
|
17
18
|
from datacontract.engines.soda.connections.kafka import create_spark_session, read_kafka_topic
|
|
18
19
|
from datacontract.engines.soda.connections.postgres import to_postgres_soda_configuration
|
|
19
20
|
from datacontract.engines.soda.connections.snowflake import to_snowflake_soda_configuration
|
|
@@ -95,6 +96,18 @@ def check_soda_execute(
|
|
|
95
96
|
logging.info("Use Spark to connect to data source")
|
|
96
97
|
scan.add_spark_session(spark, data_source_name="datacontract-cli")
|
|
97
98
|
scan.set_data_source_name("datacontract-cli")
|
|
99
|
+
|
|
100
|
+
# ------------------------------------------------------------------
|
|
101
|
+
# NEW: native Impala server type
|
|
102
|
+
# ------------------------------------------------------------------
|
|
103
|
+
elif server.type == "impala":
|
|
104
|
+
run.log_info("Connecting to Impala via Soda engine")
|
|
105
|
+
soda_configuration_str = to_impala_soda_configuration(server)
|
|
106
|
+
scan.add_configuration_yaml_str(soda_configuration_str)
|
|
107
|
+
# data source name must match what we configure in to_impala_soda_configuration
|
|
108
|
+
scan.set_data_source_name("impala")
|
|
109
|
+
|
|
110
|
+
|
|
98
111
|
elif server.type == "kafka":
|
|
99
112
|
if spark is None:
|
|
100
113
|
spark = create_spark_session()
|
|
@@ -218,4 +231,4 @@ def update_reason(check, c):
|
|
|
218
231
|
# print(check.reason)
|
|
219
232
|
break # Exit the loop once the desired block is found
|
|
220
233
|
if "fail" in c["diagnostics"]:
|
|
221
|
-
check.reason = f"Value: {c['diagnostics']['value']} Fail: {c['diagnostics']['fail']}"
|
|
234
|
+
check.reason = f"Value: {c['diagnostics']['value']} Fail: {c['diagnostics']['fail']}"
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import re
|
|
2
3
|
from typing import Any, List, Optional
|
|
3
4
|
|
|
4
5
|
import duckdb
|
|
5
6
|
from open_data_contract_standard.model import OpenDataContractStandard, SchemaObject, SchemaProperty, Server
|
|
6
7
|
|
|
7
8
|
from datacontract.export.duckdb_type_converter import convert_to_duckdb_csv_type, convert_to_duckdb_json_type
|
|
9
|
+
from datacontract.export.sql_type_converter import convert_to_duckdb
|
|
8
10
|
from datacontract.model.run import Run
|
|
9
11
|
|
|
10
12
|
|
|
@@ -57,20 +59,9 @@ def get_duckdb_connection(
|
|
|
57
59
|
)
|
|
58
60
|
add_nested_views(con, model_name, schema_obj.properties)
|
|
59
61
|
elif server.format == "parquet":
|
|
60
|
-
con
|
|
61
|
-
CREATE VIEW "{model_name}" AS SELECT * FROM read_parquet('{model_path}', hive_partitioning=1);
|
|
62
|
-
""")
|
|
62
|
+
create_view_with_schema_union(con, schema_obj, model_path, "read_parquet", to_parquet_types)
|
|
63
63
|
elif server.format == "csv":
|
|
64
|
-
|
|
65
|
-
run.log_info("Using columns: " + str(columns))
|
|
66
|
-
if columns is None:
|
|
67
|
-
con.sql(
|
|
68
|
-
f"""CREATE VIEW "{model_name}" AS SELECT * FROM read_csv('{model_path}', hive_partitioning=1);"""
|
|
69
|
-
)
|
|
70
|
-
else:
|
|
71
|
-
con.sql(
|
|
72
|
-
f"""CREATE VIEW "{model_name}" AS SELECT * FROM read_csv('{model_path}', hive_partitioning=1, columns={columns});"""
|
|
73
|
-
)
|
|
64
|
+
create_view_with_schema_union(con, schema_obj, model_path, "read_csv", to_csv_types)
|
|
74
65
|
elif server.format == "delta":
|
|
75
66
|
con.sql("update extensions;") # Make sure we have the latest delta extension
|
|
76
67
|
con.sql(f"""CREATE VIEW "{model_name}" AS SELECT * FROM delta_scan('{model_path}');""")
|
|
@@ -80,6 +71,34 @@ def get_duckdb_connection(
|
|
|
80
71
|
return con
|
|
81
72
|
|
|
82
73
|
|
|
74
|
+
def create_view_with_schema_union(con, schema_obj: SchemaObject, model_path: str, read_function: str, type_converter):
|
|
75
|
+
"""Create a view by unioning empty schema table with data files using union_by_name"""
|
|
76
|
+
converted_types = type_converter(schema_obj)
|
|
77
|
+
model_name = schema_obj.name
|
|
78
|
+
if converted_types:
|
|
79
|
+
# Create empty table with contract schema
|
|
80
|
+
columns_def = [f'"{col_name}" {col_type}' for col_name, col_type in converted_types.items()]
|
|
81
|
+
create_empty_table = f"""CREATE TABLE "{model_name}" ({', '.join(columns_def)});"""
|
|
82
|
+
con.sql(create_empty_table)
|
|
83
|
+
|
|
84
|
+
# Read columns existing in both current data contract and data
|
|
85
|
+
intersecting_columns = con.sql(f"""SELECT column_name
|
|
86
|
+
FROM (DESCRIBE SELECT * FROM {read_function}('{model_path}', union_by_name=true, hive_partitioning=1))
|
|
87
|
+
INTERSECT SELECT column_name
|
|
88
|
+
FROM information_schema.columns
|
|
89
|
+
WHERE table_name = '{model_name}'""").fetchall()
|
|
90
|
+
selected_columns = ', '.join([column[0] for column in intersecting_columns])
|
|
91
|
+
|
|
92
|
+
# Insert data into table by name, but only columns existing in contract and data
|
|
93
|
+
insert_data_sql = f"""INSERT INTO {model_name} BY NAME
|
|
94
|
+
(SELECT {selected_columns} FROM {read_function}('{model_path}', union_by_name=true, hive_partitioning=1));"""
|
|
95
|
+
con.sql(insert_data_sql)
|
|
96
|
+
else:
|
|
97
|
+
# Fallback
|
|
98
|
+
con.sql(
|
|
99
|
+
f"""CREATE VIEW "{model_name}" AS SELECT * FROM {read_function}('{model_path}', union_by_name=true, hive_partitioning=1);"""
|
|
100
|
+
)
|
|
101
|
+
|
|
83
102
|
def to_csv_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
|
|
84
103
|
if schema_obj is None:
|
|
85
104
|
return None
|
|
@@ -89,6 +108,15 @@ def to_csv_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
|
|
|
89
108
|
columns[prop.name] = convert_to_duckdb_csv_type(prop)
|
|
90
109
|
return columns
|
|
91
110
|
|
|
111
|
+
def to_parquet_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
|
|
112
|
+
"""Get proper SQL types for Parquet (preserves decimals, etc.)"""
|
|
113
|
+
if schema_obj is None:
|
|
114
|
+
return None
|
|
115
|
+
columns = {}
|
|
116
|
+
if schema_obj.properties:
|
|
117
|
+
for prop in schema_obj.properties:
|
|
118
|
+
columns[prop.name] = convert_to_duckdb(prop)
|
|
119
|
+
return columns
|
|
92
120
|
|
|
93
121
|
def to_json_types(schema_obj: SchemaObject) -> dict[Any, str | None] | None:
|
|
94
122
|
if schema_obj is None:
|
|
@@ -140,7 +168,7 @@ def add_nested_views(con: duckdb.DuckDBPyConnection, model_name: str, properties
|
|
|
140
168
|
add_nested_views(con, nested_model_name, prop.properties)
|
|
141
169
|
|
|
142
170
|
|
|
143
|
-
def setup_s3_connection(con, server):
|
|
171
|
+
def setup_s3_connection(con, server: Server):
|
|
144
172
|
s3_region = os.getenv("DATACONTRACT_S3_REGION")
|
|
145
173
|
s3_access_key_id = os.getenv("DATACONTRACT_S3_ACCESS_KEY_ID")
|
|
146
174
|
s3_secret_access_key = os.getenv("DATACONTRACT_S3_SECRET_ACCESS_KEY")
|
|
@@ -184,7 +212,7 @@ def setup_s3_connection(con, server):
|
|
|
184
212
|
""")
|
|
185
213
|
|
|
186
214
|
|
|
187
|
-
def setup_gcs_connection(con, server):
|
|
215
|
+
def setup_gcs_connection(con, server: Server):
|
|
188
216
|
key_id = os.getenv("DATACONTRACT_GCS_KEY_ID")
|
|
189
217
|
secret = os.getenv("DATACONTRACT_GCS_SECRET")
|
|
190
218
|
|
|
@@ -202,11 +230,14 @@ def setup_gcs_connection(con, server):
|
|
|
202
230
|
""")
|
|
203
231
|
|
|
204
232
|
|
|
205
|
-
def setup_azure_connection(con, server):
|
|
233
|
+
def setup_azure_connection(con, server: Server):
|
|
206
234
|
tenant_id = os.getenv("DATACONTRACT_AZURE_TENANT_ID")
|
|
207
235
|
client_id = os.getenv("DATACONTRACT_AZURE_CLIENT_ID")
|
|
208
236
|
client_secret = os.getenv("DATACONTRACT_AZURE_CLIENT_SECRET")
|
|
209
|
-
storage_account =
|
|
237
|
+
storage_account = (
|
|
238
|
+
to_azure_storage_account(server.location) if server.type == "azure" and "://" in server.location
|
|
239
|
+
else None
|
|
240
|
+
)
|
|
210
241
|
|
|
211
242
|
if tenant_id is None:
|
|
212
243
|
raise ValueError("Error: Environment variable DATACONTRACT_AZURE_TENANT_ID is not set")
|
|
@@ -239,3 +270,25 @@ def setup_azure_connection(con, server):
|
|
|
239
270
|
CLIENT_SECRET '{client_secret}'
|
|
240
271
|
);
|
|
241
272
|
""")
|
|
273
|
+
|
|
274
|
+
def to_azure_storage_account(location: str) -> str | None:
|
|
275
|
+
"""
|
|
276
|
+
Converts a storage location string to extract the storage account name.
|
|
277
|
+
ODCS v3.0 has no explicit field for the storage account. It uses the location field, which is a URI.
|
|
278
|
+
This function parses a storage location string to identify and return the
|
|
279
|
+
storage account name. It handles two primary patterns:
|
|
280
|
+
1. Protocol://containerName@storageAccountName
|
|
281
|
+
2. Protocol://storageAccountName
|
|
282
|
+
:param location: The storage location string to parse, typically following
|
|
283
|
+
the format protocol://containerName@storageAccountName. or
|
|
284
|
+
protocol://storageAccountName.
|
|
285
|
+
:return: The extracted storage account name if found, otherwise None
|
|
286
|
+
"""
|
|
287
|
+
# to catch protocol://containerName@storageAccountName. pattern from location
|
|
288
|
+
match = re.search(r"(?<=@)([^.]*)", location, re.IGNORECASE)
|
|
289
|
+
if match:
|
|
290
|
+
return match.group()
|
|
291
|
+
else:
|
|
292
|
+
# to catch protocol://storageAccountName. pattern from location
|
|
293
|
+
match = re.search(r"(?<=//)(?!@)([^.]*)", location, re.IGNORECASE)
|
|
294
|
+
return match.group() if match else None
|