datacontract-cli 1.0.4__tar.gz → 1.0.5__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.
Files changed (368) hide show
  1. {datacontract_cli-1.0.4/datacontract_cli.egg-info → datacontract_cli-1.0.5}/PKG-INFO +1 -1
  2. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/checks/check_spec.py +6 -2
  3. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/checks/create_checks.py +4 -10
  4. datacontract_cli-1.0.5/datacontract/engines/checks/type_normalize.py +214 -0
  5. datacontract_cli-1.0.5/datacontract/engines/ibis/dtype_category.py +93 -0
  6. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/ibis/ibis_check_execute.py +30 -15
  7. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/dcs_importer.py +15 -8
  8. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5/datacontract_cli.egg-info}/PKG-INFO +1 -1
  9. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract_cli.egg-info/SOURCES.txt +1 -0
  10. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/pyproject.toml +1 -1
  11. datacontract_cli-1.0.5/tests/test_ibis_oracle_schema.py +82 -0
  12. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_diagnostics.py +4 -2
  13. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_parquet.py +1 -1
  14. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_type_normalize.py +1 -11
  15. datacontract_cli-1.0.4/datacontract/engines/checks/type_normalize.py +0 -139
  16. datacontract_cli-1.0.4/datacontract/engines/ibis/dtype_category.py +0 -41
  17. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/LICENSE +0 -0
  18. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/MANIFEST.in +0 -0
  19. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/README.md +0 -0
  20. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/__init__.py +0 -0
  21. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/api.py +0 -0
  22. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/catalog/catalog.py +0 -0
  23. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/changelog/__init__.py +0 -0
  24. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/changelog/changelog.py +0 -0
  25. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/changelog/normalize.py +0 -0
  26. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/cli.py +0 -0
  27. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_api.py +0 -0
  28. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_catalog.py +0 -0
  29. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_changelog.py +0 -0
  30. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_ci.py +0 -0
  31. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_dbt.py +0 -0
  32. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_edit.py +0 -0
  33. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_export.py +0 -0
  34. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_import.py +0 -0
  35. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_init.py +0 -0
  36. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_lint.py +0 -0
  37. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_publish.py +0 -0
  38. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/command_test.py +0 -0
  39. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/data_contract.py +0 -0
  40. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/VERSION +0 -0
  41. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/abap-Bs8kvjsq.js +0 -0
  42. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/apex-Dspwrl5m.js +0 -0
  43. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/assets/editor.worker-4.7.0.js +0 -0
  44. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/assets/yaml.worker-4.7.0.js +0 -0
  45. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/azcli-k1BiOau1.js +0 -0
  46. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/bat-BIP72KWc.js +0 -0
  47. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/bicep-VhQeYhS3.js +0 -0
  48. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/cameligo-DnuAXtHg.js +0 -0
  49. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/clojure-BAuDPsal.js +0 -0
  50. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/coffee-BV06qSnj.js +0 -0
  51. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/cpp-Cz8Jeyrf.js +0 -0
  52. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/csharp-F6hhlXFb.js +0 -0
  53. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/csp-KzlEHCyI.js +0 -0
  54. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/css-e4FKntZ3.js +0 -0
  55. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/cssMode-BNkTa2xp.js +0 -0
  56. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/cypher-CpvDGKRr.js +0 -0
  57. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/dart-DdHeFWR0.js +0 -0
  58. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/datacontract-editor.css +0 -0
  59. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/datacontract-editor.es.js +0 -0
  60. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/dockerfile-aoNXDcio.js +0 -0
  61. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/ecl-C4Q0DYuA.js +0 -0
  62. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/elixir-C9X42b0T.js +0 -0
  63. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/flow9-Bff42pfB.js +0 -0
  64. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/freemarker2-Dyfzmb5A.js +0 -0
  65. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/fsharp-C6vPAsHG.js +0 -0
  66. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/go-DEr8zx9f.js +0 -0
  67. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/graphql-BiNBBRFh.js +0 -0
  68. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/handlebars-BtDNI-uC.js +0 -0
  69. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/hcl-2T9lKuFg.js +0 -0
  70. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/html-Cn4TGw_o.js +0 -0
  71. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/htmlMode-Bf84vbo2.js +0 -0
  72. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/index.html +0 -0
  73. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/ini-CZGtssYM.js +0 -0
  74. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/java-B260NeH3.js +0 -0
  75. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/javascript-B86Kac07.js +0 -0
  76. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/jsonMode-Ckgg5lAE.js +0 -0
  77. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/julia-kuNLM9c5.js +0 -0
  78. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/kotlin-Bz6kAefA.js +0 -0
  79. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/less-AZUtS89I.js +0 -0
  80. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/lexon-BcmgnyRb.js +0 -0
  81. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/liquid-D0NPwuu_.js +0 -0
  82. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/logo_fuchsia_v2.svg +0 -0
  83. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/lua-Dz1RbATg.js +0 -0
  84. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/m3-CIMooLFn.js +0 -0
  85. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/markdown-C1BsCK9P.js +0 -0
  86. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/mdx-QFRSBtVQ.js +0 -0
  87. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/mips-BovsnfLQ.js +0 -0
  88. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/monaco-4.7.0.js +0 -0
  89. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/msdax-CiRB2ZB-.js +0 -0
  90. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/mysql-BwdpPE19.js +0 -0
  91. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/objective-c-D4nfHfso.js +0 -0
  92. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/odcs.svg +0 -0
  93. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/pascal--j5-PYtz.js +0 -0
  94. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/pascaligo-C7TcJxNL.js +0 -0
  95. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/perl-BzEWqUb5.js +0 -0
  96. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/pgsql-B_KZ0mGX.js +0 -0
  97. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/php-A19QHzQV.js +0 -0
  98. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/pla-COeKY1hA.js +0 -0
  99. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/postiats-BfMp7zJL.js +0 -0
  100. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/powerquery-B0TS_5Gb.js +0 -0
  101. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/powershell-5jSbKdYB.js +0 -0
  102. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/protobuf-YgnOutn3.js +0 -0
  103. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/pug-DLej6kn5.js +0 -0
  104. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/python-C8RW9B6A.js +0 -0
  105. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/qsharp-AhjqtSHB.js +0 -0
  106. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/r-D-F4P80w.js +0 -0
  107. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/razor-CLZqdY_r.js +0 -0
  108. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/redis-hwwIlMnV.js +0 -0
  109. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/redshift-Bcm_kjEG.js +0 -0
  110. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/restructuredtext-CrdzfPP-.js +0 -0
  111. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/ruby-QC2UNm1s.js +0 -0
  112. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/rust-5aqiQ3L5.js +0 -0
  113. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/sb-B1g1ZfLJ.js +0 -0
  114. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/scala-C2U4R5Gb.js +0 -0
  115. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/scheme-DeFRbslr.js +0 -0
  116. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/scss-RSTCiCmI.js +0 -0
  117. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/shell-BpF-iNu8.js +0 -0
  118. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/solidity-C00r2mbQ.js +0 -0
  119. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/sophia-DVW5ZKDB.js +0 -0
  120. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/sparql-B0nmpxeX.js +0 -0
  121. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/sql-CJwKPERn.js +0 -0
  122. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/st-DPlKG5DT.js +0 -0
  123. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/swift-YZBAbVHV.js +0 -0
  124. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/systemverilog-CDQSaH63.js +0 -0
  125. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/tcl-Dlu8sp6Q.js +0 -0
  126. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/tsMode-yleMwhPq.js +0 -0
  127. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/twig-C5TO7-kw.js +0 -0
  128. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/typescript-CJBeebKU.js +0 -0
  129. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/typespec-BsmjDEu7.js +0 -0
  130. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/vb-ChHvIDrk.js +0 -0
  131. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/wgsl-XEp1ju8c.js +0 -0
  132. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/xml-vC-NMVX1.js +0 -0
  133. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/editor_assets/yaml-Dlf2VF-T.js +0 -0
  134. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/__init__.py +0 -0
  135. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/checks/__init__.py +0 -0
  136. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/data_contract_test.py +0 -0
  137. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/datacontract/check_azure_blob_file.py +0 -0
  138. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/datacontract/check_that_datacontract_contains_valid_servers_configuration.py +0 -0
  139. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/datacontract/check_that_datacontract_file_exists.py +0 -0
  140. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/fastjsonschema/check_jsonschema.py +0 -0
  141. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/fastjsonschema/s3/s3_read_files.py +0 -0
  142. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/ibis/__init__.py +0 -0
  143. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/ibis/connections/__init__.py +0 -0
  144. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/ibis/connections/connect.py +0 -0
  145. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/ibis/connections/duckdb_connection.py +0 -0
  146. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/ibis/connections/kafka.py +0 -0
  147. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/engines/ibis/connections/oracle_patch.py +0 -0
  148. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/__init__.py +0 -0
  149. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/avro_exporter.py +0 -0
  150. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/avro_idl_exporter.py +0 -0
  151. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/bigquery_exporter.py +0 -0
  152. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/custom_exporter.py +0 -0
  153. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/data_caterer_exporter.py +0 -0
  154. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/dbml_exporter.py +0 -0
  155. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/dbt_exporter.py +0 -0
  156. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/dcs_exporter.py +0 -0
  157. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/dqx_exporter.py +0 -0
  158. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/duckdb_type_converter.py +0 -0
  159. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/excel_exporter.py +0 -0
  160. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/exporter.py +0 -0
  161. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/exporter_factory.py +0 -0
  162. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/go_exporter.py +0 -0
  163. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/great_expectations_exporter.py +0 -0
  164. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/html_exporter.py +0 -0
  165. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/iceberg_exporter.py +0 -0
  166. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/jsonschema_exporter.py +0 -0
  167. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/markdown_exporter.py +0 -0
  168. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/mermaid_exporter.py +0 -0
  169. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/odcs_export_helper.py +0 -0
  170. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/odcs_v3_exporter.py +0 -0
  171. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/pandas_type_converter.py +0 -0
  172. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/protobuf_exporter.py +0 -0
  173. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/pydantic_exporter.py +0 -0
  174. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/rdf_exporter.py +0 -0
  175. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/sodacl_check_builder.py +0 -0
  176. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/sodacl_exporter.py +0 -0
  177. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/spark_exporter.py +0 -0
  178. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/sql_exporter.py +0 -0
  179. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/sql_type_converter.py +0 -0
  180. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/export/sqlalchemy_exporter.py +0 -0
  181. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/avro_importer.py +0 -0
  182. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/bigquery_importer.py +0 -0
  183. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/csv_importer.py +0 -0
  184. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/dbml_importer.py +0 -0
  185. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/dbt_importer.py +0 -0
  186. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/excel_importer.py +0 -0
  187. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/glue_importer.py +0 -0
  188. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/iceberg_importer.py +0 -0
  189. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/importer.py +0 -0
  190. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/importer_factory.py +0 -0
  191. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/json_importer.py +0 -0
  192. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/jsonschema_importer.py +0 -0
  193. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/odcs_helper.py +0 -0
  194. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/odcs_importer.py +0 -0
  195. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/parquet_importer.py +0 -0
  196. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/powerbi_importer.py +0 -0
  197. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/protobuf_importer.py +0 -0
  198. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/snowflake_importer.py +0 -0
  199. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/spark_importer.py +0 -0
  200. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/sql_importer.py +0 -0
  201. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/imports/unity_importer.py +0 -0
  202. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/init/init_template.py +0 -0
  203. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/integration/dbt_sync.py +0 -0
  204. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/integration/dbt_test_mapping.py +0 -0
  205. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/integration/entropy_data.py +0 -0
  206. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/lint/files.py +0 -0
  207. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/lint/resolve.py +0 -0
  208. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/lint/resources.py +0 -0
  209. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/lint/schema.py +0 -0
  210. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/lint/urls.py +0 -0
  211. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/model/changelog.py +0 -0
  212. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/model/exceptions.py +0 -0
  213. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/model/odcs.py +0 -0
  214. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/model/run.py +0 -0
  215. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/model/server.py +0 -0
  216. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/output/__init__.py +0 -0
  217. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/output/ci_output.py +0 -0
  218. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/output/json_test_results.py +0 -0
  219. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/output/junit_test_results.py +0 -0
  220. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/output/output_format.py +0 -0
  221. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/output/test_results_writer.py +0 -0
  222. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/output/text_changelog_results.py +0 -0
  223. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/py.typed +0 -0
  224. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/datacontract-1.1.0.init.yaml +0 -0
  225. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/datacontract-1.1.0.schema.json +0 -0
  226. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/datacontract-1.2.0.init.yaml +0 -0
  227. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/datacontract-1.2.0.schema.json +0 -0
  228. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/datacontract-1.2.1.init.yaml +0 -0
  229. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/datacontract-1.2.1.schema.json +0 -0
  230. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/odcs-3.0.1.schema.json +0 -0
  231. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/odcs-3.0.2.schema.json +0 -0
  232. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/odcs-3.1.0.init.yaml +0 -0
  233. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/schemas/odcs-3.1.0.schema.json +0 -0
  234. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/datacontract.html +0 -0
  235. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/datacontract_odcs.html +0 -0
  236. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/index.html +0 -0
  237. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/datacontract_information.html +0 -0
  238. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/datacontract_servicelevels.html +0 -0
  239. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/datacontract_terms.html +0 -0
  240. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/definition.html +0 -0
  241. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/example.html +0 -0
  242. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/model_field.html +0 -0
  243. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/quality.html +0 -0
  244. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/partials/server.html +0 -0
  245. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract/templates/style/output.css +0 -0
  246. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract_cli.egg-info/dependency_links.txt +0 -0
  247. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract_cli.egg-info/entry_points.txt +0 -0
  248. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract_cli.egg-info/requires.txt +0 -0
  249. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/datacontract_cli.egg-info/top_level.txt +0 -0
  250. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/setup.cfg +0 -0
  251. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_api.py +0 -0
  252. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_catalog.py +0 -0
  253. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_changelog.py +0 -0
  254. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_changelog_engine.py +0 -0
  255. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_changelog_normalize.py +0 -0
  256. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_changelog_output_text.py +0 -0
  257. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_ci_output.py +0 -0
  258. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_cli.py +0 -0
  259. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_connect_databricks.py +0 -0
  260. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_connect_sqlserver.py +0 -0
  261. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_connect_trino.py +0 -0
  262. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_data_contract.py +0 -0
  263. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_data_contract_checks.py +0 -0
  264. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_data_contract_specification.py +0 -0
  265. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_dbt_sync.py +0 -0
  266. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_dbt_test_mapping.py +0 -0
  267. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_description_linter.py +0 -0
  268. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_download_datacontract_file.py +0 -0
  269. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_duckdb_json.py +0 -0
  270. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_edit.py +0 -0
  271. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_avro.py +0 -0
  272. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_avro_idl.py +0 -0
  273. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_bigquery.py +0 -0
  274. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_complex_data_contract.py +0 -0
  275. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_custom.py +0 -0
  276. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_custom_exporter.py +0 -0
  277. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_custom_model.py +0 -0
  278. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_data_caterer.py +0 -0
  279. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_dbml.py +0 -0
  280. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_dbt_models.py +0 -0
  281. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_dbt_sources.py +0 -0
  282. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_dbt_staging_sql.py +0 -0
  283. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_dqx.py +0 -0
  284. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_excel.py +0 -0
  285. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_go.py +0 -0
  286. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_great_expectations.py +0 -0
  287. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_html.py +0 -0
  288. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_iceberg.py +0 -0
  289. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_jsonschema.py +0 -0
  290. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_markdown.py +0 -0
  291. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_mermaid.py +0 -0
  292. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_odcs_v3.py +0 -0
  293. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_protobuf.py +0 -0
  294. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_pydantic.py +0 -0
  295. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_rdf.py +0 -0
  296. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_sodacl.py +0 -0
  297. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_spark.py +0 -0
  298. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_sql.py +0 -0
  299. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_sql_clickhouse.py +0 -0
  300. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_sql_query.py +0 -0
  301. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_export_sqlalchemy.py +0 -0
  302. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_ibis_mssql_pattern.py +0 -0
  303. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_avro.py +0 -0
  304. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_bigquery.py +0 -0
  305. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_csv.py +0 -0
  306. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_dbml.py +0 -0
  307. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_dbt.py +0 -0
  308. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_excel.py +0 -0
  309. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_glue.py +0 -0
  310. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_iceberg.py +0 -0
  311. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_json.py +0 -0
  312. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_jsonschema.py +0 -0
  313. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_odcs_v3.py +0 -0
  314. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_parquet.py +0 -0
  315. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_powerbi.py +0 -0
  316. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_protobuf.py +0 -0
  317. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_snowflake.py +0 -0
  318. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_spark.py +0 -0
  319. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_sql_oracle.py +0 -0
  320. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_sql_postgres.py +0 -0
  321. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_sql_snowflake.py +0 -0
  322. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_sql_sqlserver.py +0 -0
  323. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_import_unity_file.py +0 -0
  324. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_integration_entropydata.py +0 -0
  325. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_lint.py +0 -0
  326. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_oracle_patch.py +0 -0
  327. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_require_env.py +0 -0
  328. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_resolve.py +0 -0
  329. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_resolve_definitions.py +0 -0
  330. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_roundtrip_jsonschema.py +0 -0
  331. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_sql_type_converter_physicaltype.py +0 -0
  332. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_api.py +0 -0
  333. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_athena_iceberg.py +0 -0
  334. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_azure_blob_file.py +0 -0
  335. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_azure_remote.py +0 -0
  336. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_bigquery.py +0 -0
  337. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_checks_filter.py +0 -0
  338. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_databricks.py +0 -0
  339. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_dataframe.py +0 -0
  340. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_delta.py +0 -0
  341. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_failed_samples.py +0 -0
  342. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_gcs_csv_remote.py +0 -0
  343. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_gcs_json_remote.py +0 -0
  344. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_kafka.py +0 -0
  345. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_kafka_remote.py +0 -0
  346. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_local_json.py +0 -0
  347. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_local_json_nd.py +0 -0
  348. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_mysql.py +0 -0
  349. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_oracle.py +0 -0
  350. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_oracle_xe.py +0 -0
  351. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_output_json.py +0 -0
  352. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_output_junit.py +0 -0
  353. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_postgres.py +0 -0
  354. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_quality.py +0 -0
  355. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_quality_local_fallback.py +0 -0
  356. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_quality_percent_severity.py +0 -0
  357. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_s3_csv.py +0 -0
  358. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_s3_delta.py +0 -0
  359. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_s3_json.py +0 -0
  360. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_s3_json_complex.py +0 -0
  361. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_s3_json_multiple_models.py +0 -0
  362. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_s3_json_remote.py +0 -0
  363. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_schema_evolution.py +0 -0
  364. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_server_not_found.py +0 -0
  365. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_snowflake.py +0 -0
  366. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_soda_connection_error.py +0 -0
  367. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_sqlserver.py +0 -0
  368. {datacontract_cli-1.0.4 → datacontract_cli-1.0.5}/tests/test_test_trino.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 1.0.4
3
+ Version: 1.0.5
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
@@ -14,7 +14,10 @@ from __future__ import annotations
14
14
 
15
15
  from dataclasses import dataclass
16
16
  from enum import Enum
17
- from typing import Any, List, Optional
17
+ from typing import TYPE_CHECKING, Any, List, Optional
18
+
19
+ if TYPE_CHECKING:
20
+ from open_data_contract_standard.model import SchemaProperty
18
21
 
19
22
 
20
23
  class MetricType(str, Enum):
@@ -116,8 +119,9 @@ class CheckSpec:
116
119
  valid_min_length: Optional[int] = None # INVALID_COUNT
117
120
  valid_max_length: Optional[int] = None # INVALID_COUNT
118
121
 
119
- expected_category: Optional[str] = None # FIELD_TYPE: normalized type category
122
+ expected_category: Optional[str] = None # FIELD_TYPE: human-readable label (display only)
120
123
  expected_type_label: Optional[str] = None # FIELD_TYPE: human-readable expected type
124
+ expected_schema_property: Optional["SchemaProperty"] = None # FIELD_TYPE: structural comparison
121
125
 
122
126
  columns: Optional[List[str]] = None # DUPLICATE_COUNT across multiple columns
123
127
 
@@ -22,7 +22,6 @@ from open_data_contract_standard.model import (
22
22
  )
23
23
 
24
24
  from datacontract.engines.checks.check_spec import CheckSpec, MetricType, Op, Threshold
25
- from datacontract.engines.checks.type_normalize import normalize_type_name
26
25
 
27
26
  logger = logging.getLogger(__name__)
28
27
 
@@ -54,12 +53,6 @@ def to_schema_name(schema_object: SchemaObject, server_type: Optional[str]) -> s
54
53
  return schema_object.name
55
54
 
56
55
 
57
- def expected_type_category(prop: SchemaProperty) -> tuple[str, str]:
58
- """Return (normalized category, human label) for a property's declared type."""
59
- label = prop.physicalType or prop.logicalType
60
- return normalize_type_name(label), (label or "")
61
-
62
-
63
56
  _PERCENT_UNITS = {"percent", "percentage", "%"}
64
57
 
65
58
 
@@ -178,8 +171,8 @@ def _to_schema_checks(schema_object: SchemaObject, server: Optional[Server]) ->
178
171
  )
179
172
  )
180
173
 
181
- if check_types and (prop.physicalType is not None or prop.logicalType is not None):
182
- category, label = expected_type_category(prop)
174
+ if check_types and prop.logicalType is not None:
175
+ schema_prop, label = prop, prop.logicalType or ""
183
176
  checks.append(
184
177
  CheckSpec(
185
178
  key=f"{model}__{field}__field_type",
@@ -189,8 +182,9 @@ def _to_schema_checks(schema_object: SchemaObject, server: Optional[Server]) ->
189
182
  model=model,
190
183
  field=field,
191
184
  metric=MetricType.FIELD_TYPE,
192
- expected_category=category,
185
+ expected_category=label,
193
186
  expected_type_label=label,
187
+ expected_schema_property=schema_prop,
194
188
  )
195
189
  )
196
190
 
@@ -0,0 +1,214 @@
1
+ """Type normalization and structural comparison for schema ``field_type`` checks.
2
+
3
+ ``normalize_type_name`` maps a raw type string (logical or physical) to one of
4
+ the nine ODCS logical-type categories.
5
+
6
+ ``schema_property_matches`` compares two ``SchemaProperty`` trees — one from the
7
+ contract, one reconstructed from the ibis-reported dtype — and returns True when
8
+ the actual type is structurally compatible with the expected one.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import re
14
+
15
+ from open_data_contract_standard.model import SchemaProperty
16
+
17
+
18
+ def normalize_type_name(type_name: str | None) -> str | None:
19
+ """Map a contract type name (logical or physical) to one of the 9 ODCS categories.
20
+
21
+ Returns ``None`` for types that are unsupported or unrecognized (binary,
22
+ map, null, interval …) so they can be silently ignored rather than
23
+ producing false type-check failures.
24
+ """
25
+ if not type_name:
26
+ return None
27
+ name = type_name.strip().lower()
28
+ # strip parameters like varchar(10) / decimal(10,2) and array<...> wrappers
29
+ name = re.sub(r"\(.*\)", "", name)
30
+ name = re.sub(r"<.*>", "", name).strip()
31
+
32
+ if name in {
33
+ "varchar",
34
+ "varchar2",
35
+ "char",
36
+ "character",
37
+ "character varying",
38
+ "nvarchar",
39
+ "nvarchar2",
40
+ "nchar",
41
+ "text",
42
+ "string",
43
+ "str",
44
+ "clob",
45
+ "nclob",
46
+ "uuid",
47
+ "enum",
48
+ }:
49
+ return "string"
50
+ if name in {
51
+ "int",
52
+ "integer",
53
+ "bigint",
54
+ "smallint",
55
+ "tinyint",
56
+ "long",
57
+ "short",
58
+ "int2",
59
+ "int4",
60
+ "int8",
61
+ "serial",
62
+ "bigserial",
63
+ "smallserial",
64
+ "int64",
65
+ "int32",
66
+ "int16",
67
+ "int8",
68
+ "byteint",
69
+ }:
70
+ return "integer"
71
+ if name in {
72
+ "decimal",
73
+ "numeric",
74
+ "dec",
75
+ "float",
76
+ "double",
77
+ "double precision",
78
+ "real",
79
+ "float4",
80
+ "float8",
81
+ "float32",
82
+ "float64",
83
+ "binary_float",
84
+ "binary_double",
85
+ "number",
86
+ }:
87
+ return "number"
88
+ if name in {"bool", "boolean", "bit", "logical"}:
89
+ return "boolean"
90
+ if name in {
91
+ "timestamp",
92
+ "timestamptz",
93
+ "timestamp without time zone",
94
+ "timestamp with time zone",
95
+ "timestamp_tz",
96
+ "timestamp_ntz",
97
+ "timestamp_ltz",
98
+ "datetime",
99
+ "datetime2",
100
+ "smalldatetime",
101
+ }:
102
+ return "timestamp"
103
+ if name in {"date"}:
104
+ return "date"
105
+ if name in {"time", "time without time zone", "time with time zone"}:
106
+ return "time"
107
+ if name in {"struct", "record", "object", "row", "json", "jsonb", "variant"}:
108
+ return "object"
109
+ if name in {"array", "list"}:
110
+ return "array"
111
+ # binary, map, null, interval and other unrecognized types are not in the
112
+ # 9 allowed categories; return None so they are silently ignored.
113
+ return None
114
+
115
+
116
+ _NUMERIC = {"integer", "number"}
117
+
118
+
119
+ def schema_property_matches(expected: SchemaProperty | None, actual: SchemaProperty | None) -> bool:
120
+ """Return True if ``actual`` is structurally compatible with ``expected``.
121
+
122
+ Lenient by design:
123
+
124
+ - If expected is ``None`` (unsupported/unrecognized type) always passes.
125
+ - ``integer`` and ``number`` are mutually compatible (ODCS "number" is
126
+ intentionally ambiguous across numeric storage classes).
127
+ - A bare ``object`` or ``array`` on the expected side (no nested detail)
128
+ matches any actual structure with the same base (underdeclared contract).
129
+ - Extra actual fields inside an ``object`` are ignored.
130
+ """
131
+ if expected is None:
132
+ return True
133
+ if actual is None:
134
+ return False
135
+
136
+ expected_base = normalize_type_name(expected.logicalType or expected.physicalType)
137
+ actual_base = normalize_type_name(actual.logicalType or actual.physicalType)
138
+
139
+ if expected_base is None:
140
+ return True
141
+ if actual_base is None:
142
+ return False
143
+ if expected_base != actual_base and not (expected_base in _NUMERIC and actual_base in _NUMERIC):
144
+ return False
145
+
146
+ if expected_base == "array":
147
+ if expected.items is None:
148
+ return True
149
+ return schema_property_matches(expected.items, actual.items)
150
+
151
+ if expected_base == "object":
152
+ if not expected.properties:
153
+ return True
154
+ actual_by_name = {p.name.lower(): p for p in (actual.properties or []) if p.name}
155
+ for exp_field in expected.properties:
156
+ if not exp_field.name:
157
+ continue
158
+ act_field = actual_by_name.get(exp_field.name.lower())
159
+ if act_field is None:
160
+ return False
161
+ if not schema_property_matches(exp_field, act_field):
162
+ return False
163
+ return True
164
+
165
+ return True
166
+
167
+
168
+ def schema_property_mismatch_reason(
169
+ expected: SchemaProperty | None,
170
+ actual: SchemaProperty | None,
171
+ path: str = "",
172
+ ) -> str:
173
+ """Return a human-readable description of the first structural mismatch, or '' if none."""
174
+ if expected is None:
175
+ return ""
176
+ field_label = f"field '{path}'" if path else "column"
177
+ if actual is None:
178
+ exp_str = expected.logicalType or expected.physicalType
179
+ return f"{field_label}: expected type '{exp_str}' but the column type could not be determined"
180
+
181
+ expected_base = normalize_type_name(expected.logicalType or expected.physicalType)
182
+ actual_base = normalize_type_name(actual.logicalType or actual.physicalType)
183
+
184
+ if expected_base is None:
185
+ return ""
186
+
187
+ if expected_base != actual_base and not (expected_base in _NUMERIC and actual_base in _NUMERIC):
188
+ exp_str = expected.logicalType or expected.physicalType
189
+ act_str = actual.logicalType or actual.physicalType
190
+ return f"{field_label}: expected type '{exp_str}' but got '{act_str}'"
191
+
192
+ if expected_base == "array":
193
+ if expected.items is not None:
194
+ child_path = f"{path}[]" if path else "[]"
195
+ return schema_property_mismatch_reason(expected.items, actual.items, child_path)
196
+ return ""
197
+
198
+ if expected_base == "object":
199
+ if not expected.properties:
200
+ return ""
201
+ actual_by_name = {p.name.lower(): p for p in (actual.properties or []) if p.name}
202
+ for exp_field in expected.properties:
203
+ if not exp_field.name:
204
+ continue
205
+ child_path = f"{path}.{exp_field.name}" if path else exp_field.name
206
+ act_field = actual_by_name.get(exp_field.name.lower())
207
+ if act_field is None:
208
+ return f"field '{child_path}' is missing"
209
+ reason = schema_property_mismatch_reason(exp_field, act_field, child_path)
210
+ if reason:
211
+ return reason
212
+ return ""
213
+
214
+ return ""
@@ -0,0 +1,93 @@
1
+ """Map an ibis dtype to the coarse category used by ``field_type`` checks."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from open_data_contract_standard.model import SchemaProperty
8
+
9
+ if TYPE_CHECKING:
10
+ from ibis.expr.datatypes import DataType
11
+
12
+
13
+ def ibis_dtype_category(dtype) -> str:
14
+ """Return the normalized category for an ibis ``DataType``.
15
+
16
+ Order matters: boolean is checked before integer (some engines model bool as
17
+ a 1-bit int), and decimal before floating.
18
+ """
19
+ try:
20
+ if dtype.is_boolean():
21
+ return "boolean"
22
+ if dtype.is_integer():
23
+ return "integer"
24
+ if dtype.is_decimal():
25
+ return "decimal"
26
+ if dtype.is_floating():
27
+ return "float"
28
+ if dtype.is_string():
29
+ return "string"
30
+ if dtype.is_timestamp():
31
+ return "timestamp"
32
+ if dtype.is_date():
33
+ return "date"
34
+ if dtype.is_time():
35
+ return "time"
36
+ if dtype.is_binary():
37
+ return "binary"
38
+ if dtype.is_struct():
39
+ return "struct"
40
+ if dtype.is_array():
41
+ return "array"
42
+ if dtype.is_map():
43
+ return "map"
44
+ if dtype.is_null():
45
+ return "null"
46
+ except AttributeError:
47
+ return "other"
48
+ return "other"
49
+
50
+
51
+ def ibis_dtype_to_schema_property(dtype: DataType) -> SchemaProperty | None:
52
+ """Map an ibis DataType to a SchemaProperty for structural type comparison.
53
+
54
+ Returns a ``SchemaProperty`` with ``logicalType`` set to one of the 9 ODCS
55
+ categories, recursively populating ``properties`` for structs and ``items``
56
+ for arrays. Returns ``None`` for unsupported types (binary, map, null, etc.)
57
+ so the caller can skip comparison rather than raising a false failure.
58
+ """
59
+ try:
60
+ if dtype.is_boolean():
61
+ return SchemaProperty(logicalType="boolean")
62
+ if dtype.is_integer():
63
+ return SchemaProperty(logicalType="integer")
64
+ if dtype.is_decimal() or dtype.is_floating():
65
+ return SchemaProperty(logicalType="number")
66
+ if dtype.is_string():
67
+ return SchemaProperty(logicalType="string")
68
+ if dtype.is_timestamp():
69
+ return SchemaProperty(logicalType="timestamp")
70
+ if dtype.is_date():
71
+ return SchemaProperty(logicalType="date")
72
+ if dtype.is_time():
73
+ return SchemaProperty(logicalType="time")
74
+ if dtype.is_struct():
75
+ properties = []
76
+ for field_name, ftype in dtype.fields.items():
77
+ child = ibis_dtype_to_schema_property(ftype)
78
+ if child is not None:
79
+ properties.append(
80
+ SchemaProperty(
81
+ name=field_name,
82
+ logicalType=child.logicalType,
83
+ items=child.items,
84
+ properties=child.properties,
85
+ )
86
+ )
87
+ return SchemaProperty(logicalType="object", properties=properties if properties else None)
88
+ if dtype.is_array():
89
+ element = ibis_dtype_to_schema_property(dtype.value_type)
90
+ return SchemaProperty(logicalType="array", items=element)
91
+ except AttributeError:
92
+ return None
93
+ return None
@@ -17,9 +17,9 @@ from typing import List, Optional
17
17
  from open_data_contract_standard.model import OpenDataContractStandard, Server
18
18
 
19
19
  from datacontract.engines.checks.check_spec import CheckSpec, MetricType
20
- from datacontract.engines.checks.type_normalize import category_matches
20
+ from datacontract.engines.checks.type_normalize import schema_property_matches, schema_property_mismatch_reason
21
21
  from datacontract.engines.ibis.connections.connect import connect_ibis
22
- from datacontract.engines.ibis.dtype_category import ibis_dtype_category
22
+ from datacontract.engines.ibis.dtype_category import ibis_dtype_to_schema_property
23
23
  from datacontract.model.exceptions import DataContractException
24
24
  from datacontract.model.run import Check, ResultEnum, Run
25
25
  from datacontract.model.server import get_server_type
@@ -177,7 +177,7 @@ def _run_model(
177
177
  include_failed_samples: bool = False,
178
178
  ):
179
179
  try:
180
- t = _resolve_table(con, model)
180
+ t = _resolve_table(con, model, _table_database(con, server))
181
181
  except Exception as e:
182
182
  logger.warning("Could not read model '%s': %s", model, e)
183
183
  _fail_all(run, specs, ResultEnum.failed, f"Could not read model '{model}': {e}")
@@ -607,31 +607,30 @@ def _run_type(run: Run, schema, columns, spec: CheckSpec):
607
607
  _set_impl(
608
608
  run,
609
609
  spec.key,
610
- f"type of '{spec.field}' is compatible with '{spec.expected_type_label}' ({spec.expected_category})",
610
+ f"type of '{spec.field}' is compatible with '{spec.expected_type_label}'",
611
611
  "introspection",
612
612
  )
613
- expected_label = f"{spec.expected_type_label} ({spec.expected_category})"
614
613
  actual_col = columns.get(spec.field.lower())
615
614
  if actual_col is None:
616
- _set_diagnostics(run, spec.key, _diag(metric="field_type", field=spec.field, expected=expected_label))
615
+ _set_diagnostics(run, spec.key, _diag(metric="field_type", field=spec.field, expected=spec.expected_type_label))
617
616
  _set_result(run, spec.key, ResultEnum.failed, f"Column '{spec.field}' is missing")
618
617
  return
619
618
  dtype = schema[actual_col]
620
- actual_category = ibis_dtype_category(dtype)
619
+ actual_prop = ibis_dtype_to_schema_property(dtype)
621
620
  _set_diagnostics(
622
621
  run,
623
622
  spec.key,
624
- _diag(metric="field_type", field=spec.field, expected=expected_label, actual=f"{dtype} ({actual_category})"),
623
+ _diag(metric="field_type", field=spec.field, expected=spec.expected_type_label, actual=str(dtype)),
625
624
  )
626
- if category_matches(spec.expected_category, actual_category):
625
+ if schema_property_matches(spec.expected_schema_property, actual_prop):
627
626
  _set_result(run, spec.key, ResultEnum.passed, None)
628
627
  else:
628
+ reason = schema_property_mismatch_reason(spec.expected_schema_property, actual_prop)
629
629
  _set_result(
630
630
  run,
631
631
  spec.key,
632
632
  ResultEnum.failed,
633
- f"Expected type '{spec.expected_type_label}' ({spec.expected_category}) "
634
- f"but column is '{dtype}' ({actual_category})",
633
+ reason or f"Expected type '{spec.expected_type_label}' but column is '{dtype}'",
635
634
  )
636
635
 
637
636
 
@@ -849,21 +848,37 @@ def _resolve_col(columns: dict, field: str) -> str:
849
848
  return actual
850
849
 
851
850
 
852
- def _resolve_table(con, model: str):
851
+ def _table_database(con, server: Optional[Server]) -> Optional[str]:
852
+ """The schema (owner) to qualify the table with, or ``None``.
853
+
854
+ Oracle logs in as one user but the tables may be owned by a different schema
855
+ (``server.schema``). ibis defaults the owner to the login user during
856
+ introspection, so an unqualified lookup raises ``TableNotFound``. Other
857
+ backends already pin the schema at connect time, so only Oracle needs this.
858
+ """
859
+ if server is None:
860
+ return None
861
+ if getattr(con, "name", None) == "oracle" and server.schema_:
862
+ return server.schema_
863
+ return None
864
+
865
+
866
+ def _resolve_table(con, model: str, database: Optional[str] = None):
853
867
  """Resolve a table by name, tolerating case differences across dialects."""
854
868
  if getattr(con, "name", None) == "pyspark":
855
869
  return _pyspark_table_unconvertible_as_unknown(con, model)
870
+ kwargs = {"database": database} if database else {}
856
871
  try:
857
- return con.table(model)
872
+ return con.table(model, **kwargs)
858
873
  except Exception:
859
874
  try:
860
- available = con.list_tables()
875
+ available = con.list_tables(**kwargs)
861
876
  except Exception:
862
877
  raise
863
878
  match = next((name for name in available if name.lower() == model.lower()), None)
864
879
  if match is None:
865
880
  raise
866
- return con.table(match)
881
+ return con.table(match, **kwargs)
867
882
 
868
883
 
869
884
  def _pyspark_table_unconvertible_as_unknown(con, name: str):
@@ -570,10 +570,10 @@ def _convert_field_to_property(
570
570
  return prop
571
571
 
572
572
 
573
- def _convert_type_to_logical_type(dcs_type: str) -> str:
573
+ def _convert_type_to_logical_type(dcs_type: str) -> str | None:
574
574
  """Convert DCS type to ODCS logical type."""
575
575
  if dcs_type is None:
576
- return "string"
576
+ return None
577
577
 
578
578
  t = dcs_type.lower()
579
579
 
@@ -598,19 +598,26 @@ def _convert_type_to_logical_type(dcs_type: str) -> str:
598
598
  "timestamp_tz": "timestamp",
599
599
  "timestamp_ntz": "timestamp",
600
600
  "date": "date",
601
- "time": "string", # not supported in ODCS
601
+ "time": None, # not supported in ODCS
602
602
  "datetime": "timestamp",
603
603
  "array": "array",
604
604
  "object": "object",
605
605
  "record": "object",
606
606
  "struct": "object",
607
- "map": "object",
608
- "bytes": "string", # not supported in ODCS
609
- "binary": "string", # not supported in ODCS
610
- "null": "string", # not supported in ODCS
607
+ "map": None, # not supported in ODCS
608
+ "interval": None, # not supported in ODCS
609
+ "bytes": None, # not supported in ODCS
610
+ "binary": None, # not supported in ODCS
611
+ "varbinary": None, # not supported in ODCS
612
+ "blob": None, # not supported in ODCS
613
+ "bytea": None, # not supported in ODCS
614
+ "raw": None, # not supported in ODCS
615
+ "null": None, # not supported in ODCS
616
+ "none": None, # not supported in ODCS
617
+ "void": None, # not supported in ODCS
611
618
  }
612
619
 
613
- return type_mapping.get(t, t)
620
+ return type_mapping.get(t, None)
614
621
 
615
622
 
616
623
  def _convert_quality_list(quality_list: list) -> List[DataQuality]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datacontract-cli
3
- Version: 1.0.4
3
+ Version: 1.0.5
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
@@ -292,6 +292,7 @@ tests/test_export_sql_clickhouse.py
292
292
  tests/test_export_sql_query.py
293
293
  tests/test_export_sqlalchemy.py
294
294
  tests/test_ibis_mssql_pattern.py
295
+ tests/test_ibis_oracle_schema.py
295
296
  tests/test_import_avro.py
296
297
  tests/test_import_bigquery.py
297
298
  tests/test_import_csv.py
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datacontract-cli"
3
- version = "1.0.4"
3
+ version = "1.0.5"
4
4
  description = "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
  license = "MIT"
6
6
  readme = "README.md"
@@ -0,0 +1,82 @@
1
+ """Unit tests for Oracle table resolution across schemas (owners).
2
+
3
+ Oracle logs in as one user but the contract's tables may be owned by a different
4
+ schema (``server.schema``). ibis defaults the owner to the login user during
5
+ introspection, so an unqualified lookup raises ``TableNotFound``. The engine
6
+ must qualify the table with the configured schema. See issue: cross-schema
7
+ Oracle test fails with "Could not read model '<table>': <table>".
8
+ """
9
+
10
+ from open_data_contract_standard.model import Server
11
+
12
+ from datacontract.engines.ibis.ibis_check_execute import _resolve_table, _table_database
13
+
14
+
15
+ class _FakeBackend:
16
+ """Minimal stand-in for an ibis backend that records how it is queried."""
17
+
18
+ def __init__(self, name, tables):
19
+ self.name = name
20
+ # tables: {database_or_None: {table_name: object}}
21
+ self._tables = tables
22
+ self.table_calls = []
23
+
24
+ def table(self, name, database=None):
25
+ self.table_calls.append((name, database))
26
+ try:
27
+ return self._tables[database][name]
28
+ except KeyError:
29
+ raise Exception(name)
30
+
31
+ def list_tables(self, database=None):
32
+ return list(self._tables.get(database, {}))
33
+
34
+
35
+ def test_table_database_uses_server_schema_for_oracle():
36
+ server = Server(type="oracle", schema="PSD1_VERBIS")
37
+ con = _FakeBackend("oracle", {})
38
+ assert _table_database(con, server) == "PSD1_VERBIS"
39
+
40
+
41
+ def test_table_database_none_for_oracle_without_schema():
42
+ server = Server(type="oracle")
43
+ con = _FakeBackend("oracle", {})
44
+ assert _table_database(con, server) is None
45
+
46
+
47
+ def test_table_database_none_for_non_oracle_backend():
48
+ # Postgres/snowflake pin the schema at connect time, so no qualifier is added.
49
+ server = Server(type="postgres", schema="public")
50
+ con = _FakeBackend("postgres", {})
51
+ assert _table_database(con, server) is None
52
+
53
+
54
+ def test_table_database_none_without_server():
55
+ con = _FakeBackend("oracle", {})
56
+ assert _table_database(con, None) is None
57
+
58
+
59
+ def test_resolve_table_qualifies_with_schema():
60
+ sentinel = object()
61
+ con = _FakeBackend("oracle", {"PSD1_VERBIS": {"BERUF": sentinel}})
62
+
63
+ assert _resolve_table(con, "BERUF", "PSD1_VERBIS") is sentinel
64
+ assert ("BERUF", "PSD1_VERBIS") in con.table_calls
65
+
66
+
67
+ def test_resolve_table_without_schema_does_not_pass_database():
68
+ sentinel = object()
69
+ con = _FakeBackend("oracle", {None: {"BERUF": sentinel}})
70
+
71
+ assert _resolve_table(con, "BERUF") is sentinel
72
+ assert con.table_calls == [("BERUF", None)]
73
+
74
+
75
+ def test_resolve_table_case_insensitive_fallback_keeps_schema():
76
+ sentinel = object()
77
+ con = _FakeBackend("oracle", {"PSD1_VERBIS": {"BERUF": sentinel}})
78
+
79
+ # Contract uses lowercase; the actual table is uppercase in the schema.
80
+ assert _resolve_table(con, "beruf", "PSD1_VERBIS") is sentinel
81
+ # The successful resolution still targets the qualifying schema.
82
+ assert con.table_calls[-1] == ("BERUF", "PSD1_VERBIS")
@@ -8,6 +8,7 @@ report the validity rule they enforced.
8
8
 
9
9
  import ibis
10
10
  import pandas as pd
11
+ from open_data_contract_standard.model import SchemaProperty
11
12
 
12
13
  from datacontract.data_contract import DataContract
13
14
  from datacontract.engines.checks.check_spec import CheckSpec, MetricType
@@ -89,8 +90,9 @@ def test_diagnostics_field_type_mismatch():
89
90
  model="m",
90
91
  metric=MetricType.FIELD_TYPE,
91
92
  field="amount",
92
- expected_category="number",
93
+ expected_category="integer",
93
94
  expected_type_label="integer",
95
+ expected_schema_property=SchemaProperty(logicalType="integer"),
94
96
  )
95
97
  run = _run_with([spec])
96
98
 
@@ -99,7 +101,7 @@ def test_diagnostics_field_type_mismatch():
99
101
  check = run.checks[0]
100
102
  assert check.result == ResultEnum.failed
101
103
  assert check.diagnostics["metric"] == "field_type"
102
- assert check.diagnostics["expected"] == "integer (number)"
104
+ assert check.diagnostics["expected"] == "integer"
103
105
  assert "string" in check.diagnostics["actual"]
104
106
 
105
107