snowflake-sqlalchemy 1.7.3__tar.gz → 1.7.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 (127) hide show
  1. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/DESCRIPTION.md +10 -0
  2. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/PKG-INFO +24 -2
  3. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/README.md +23 -1
  4. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/base.py +7 -8
  5. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/snowdialect.py +8 -26
  6. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/version.py +1 -1
  7. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/conftest.py +6 -0
  8. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_reflect_snowflake_table.ambr +3 -0
  9. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_create_iceberg_table.py +6 -3
  10. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_reflect_snowflake_table.py +30 -0
  11. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_copy.py +4 -4
  12. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/.gitignore +0 -0
  13. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/.gitmodules +0 -0
  14. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/.pre-commit-config.yaml +0 -0
  15. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/LICENSE.txt +0 -0
  16. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/MANIFEST.in +0 -0
  17. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/build.sh +0 -0
  18. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/build_docker.sh +0 -0
  19. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/docker/sqlalchemy_build/Dockerfile +0 -0
  20. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/docker/sqlalchemy_build/scripts/entrypoint.sh +0 -0
  21. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/set_base_image.sh +0 -0
  22. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/test.sh +0 -0
  23. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/test_docker.sh +0 -0
  24. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/ci/test_linux.sh +0 -0
  25. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/license_header.txt +0 -0
  26. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/pyproject.toml +0 -0
  27. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/setup.cfg +0 -0
  28. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/snyk/requirements.txt +0 -0
  29. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/snyk/requiremtnts.txt +0 -0
  30. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/snyk/update_requirements.py +0 -0
  31. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/__init__.py +0 -0
  32. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/_constants.py +0 -0
  33. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/compat.py +0 -0
  34. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/custom_commands.py +0 -0
  35. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/custom_types.py +0 -0
  36. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/exc.py +0 -0
  37. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/functions.py +0 -0
  38. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/parser/custom_type_parser.py +0 -0
  39. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/provision.py +0 -0
  40. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/requirements.py +0 -0
  41. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/__init__.py +0 -0
  42. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/__init__.py +0 -0
  43. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/clustered_table.py +0 -0
  44. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/custom_table_base.py +0 -0
  45. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/custom_table_prefix.py +0 -0
  46. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/dynamic_table.py +0 -0
  47. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/hybrid_table.py +0 -0
  48. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/iceberg_table.py +0 -0
  49. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/__init__.py +0 -0
  50. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/as_query_option.py +0 -0
  51. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/cluster_by_option.py +0 -0
  52. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/identifier_option.py +0 -0
  53. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/invalid_table_option.py +0 -0
  54. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/keyword_option.py +0 -0
  55. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/keywords.py +0 -0
  56. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/literal_option.py +0 -0
  57. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/table_option.py +0 -0
  58. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/options/target_lag_option.py +0 -0
  59. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/snowflake_table.py +0 -0
  60. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/sql/custom_schema/table_from_query.py +0 -0
  61. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/src/snowflake/sqlalchemy/util.py +0 -0
  62. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tested_requirements/requirements_310.reqs +0 -0
  63. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tested_requirements/requirements_37.reqs +0 -0
  64. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tested_requirements/requirements_38.reqs +0 -0
  65. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tested_requirements/requirements_39.reqs +0 -0
  66. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/README.rst +0 -0
  67. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/__init__.py +0 -0
  68. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/__snapshots__/test_compile_dynamic_table.ambr +0 -0
  69. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/__snapshots__/test_core.ambr +0 -0
  70. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/__snapshots__/test_orm.ambr +0 -0
  71. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/__snapshots__/test_reflect_dynamic_table.ambr +0 -0
  72. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/__snapshots__/test_structured_datatypes.ambr +0 -0
  73. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/__snapshots__/test_unit_structured_types.ambr +0 -0
  74. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__init__.py +0 -0
  75. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_compile_dynamic_table.ambr +0 -0
  76. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_compile_hybrid_table.ambr +0 -0
  77. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_compile_iceberg_table.ambr +0 -0
  78. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_compile_snowflake_table.ambr +0 -0
  79. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_create_dynamic_table.ambr +0 -0
  80. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_create_hybrid_table.ambr +0 -0
  81. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_create_iceberg_table.ambr +0 -0
  82. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_create_snowflake_table.ambr +0 -0
  83. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_generic_options.ambr +0 -0
  84. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/__snapshots__/test_reflect_hybrid_table.ambr +0 -0
  85. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_compile_dynamic_table.py +0 -0
  86. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_compile_hybrid_table.py +0 -0
  87. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_compile_iceberg_table.py +0 -0
  88. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_compile_snowflake_table.py +0 -0
  89. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_create_dynamic_table.py +0 -0
  90. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_create_hybrid_table.py +0 -0
  91. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_create_snowflake_table.py +0 -0
  92. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_generic_options.py +0 -0
  93. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_reflect_dynamic_table.py +0 -0
  94. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/custom_tables/test_reflect_hybrid_table.py +0 -0
  95. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/data/users.txt +0 -0
  96. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/sqlalchemy_test_suite/README.md +0 -0
  97. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/sqlalchemy_test_suite/__init__.py +0 -0
  98. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/sqlalchemy_test_suite/conftest.py +0 -0
  99. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/sqlalchemy_test_suite/test_suite.py +0 -0
  100. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/sqlalchemy_test_suite/test_suite_20.py +0 -0
  101. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_compiler.py +0 -0
  102. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_core.py +0 -0
  103. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_create.py +0 -0
  104. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_custom_functions.py +0 -0
  105. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_custom_types.py +0 -0
  106. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_geography.py +0 -0
  107. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_geometry.py +0 -0
  108. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_imports.py +0 -0
  109. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_index_reflection.py +0 -0
  110. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_multivalues_insert.py +0 -0
  111. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_orm.py +0 -0
  112. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_pandas.py +0 -0
  113. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_qmark.py +0 -0
  114. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_quote.py +0 -0
  115. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_quote_identifiers.py +0 -0
  116. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_semi_structured_datatypes.py +0 -0
  117. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_sequence.py +0 -0
  118. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_structured_datatypes.py +0 -0
  119. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_timestamp.py +0 -0
  120. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_transactions.py +0 -0
  121. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_unit_core.py +0 -0
  122. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_unit_cte.py +0 -0
  123. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_unit_structured_types.py +0 -0
  124. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_unit_types.py +0 -0
  125. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/test_unit_url.py +0 -0
  126. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tests/util.py +0 -0
  127. {snowflake_sqlalchemy-1.7.3 → snowflake_sqlalchemy-1.7.5}/tox.ini +0 -0
@@ -6,8 +6,18 @@ Snowflake Documentation is available at:
6
6
 
7
7
  Source code is also available at:
8
8
  <https://github.com/snowflakedb/snowflake-sqlalchemy>
9
+ # Unreleased Notes
10
+ - Compiling Merge and Copy Into
9
11
 
10
12
  # Release Notes
13
+ - v1.7.5(June 20, 2025)
14
+ - Fix compilation of Merge and Copy Into was not working
15
+
16
+ - v1.7.4(June 10, 2025)
17
+ - Fix dependency on DESCRIBE TABLE columns quantity (differences in columns caused by Snowflake parameters).
18
+ - Fix unnecessary condition was causing issues when parsing StructuredTypes columns.
19
+ - Update README.md to include instructions on how to verify package signatures using cosign.
20
+
11
21
  - v1.7.3(January 15, 2025)
12
22
  - Fix support for SqlAlchemy ARRAY.
13
23
  - Fix return value of snowflake get_table_names.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowflake-sqlalchemy
3
- Version: 1.7.3
3
+ Version: 1.7.5
4
4
  Summary: Snowflake SQLAlchemy Dialect
5
5
  Project-URL: Changelog, https://github.com/snowflakedb/snowflake-sqlalchemy/blob/main/DESCRIPTION.md
6
6
  Project-URL: Documentation, https://docs.snowflake.com/en/user-guide/sqlalchemy.html
@@ -63,7 +63,7 @@ Description-Content-Type: text/markdown
63
63
  Snowflake SQLAlchemy runs on the top of the Snowflake Connector for Python as a [dialect](http://docs.sqlalchemy.org/en/latest/dialects/) to bridge a Snowflake database and SQLAlchemy applications.
64
64
 
65
65
 
66
- | :exclamation: | For production-affecting or urgent issues related to the connector, please [create a case with Snowflake Support](https://community.snowflake.com/s/article/How-To-Submit-a-Support-Case-in-Snowflake-Lodge). |
66
+ | :exclamation: | Effective May 8th, 2025, Snowflake SQLAlchemy will transition to maintenance mode and will cease active development. Support will be limited to addressing critical bugs and security vulnerabilities. To report such issues, please [create a case with Snowflake Support](https://community.snowflake.com/s/article/How-To-Submit-a-Support-Case-in-Snowflake-Lodge). for individual evaluation. Please note that pull requests from external contributors may not receive action from Snowflake. |
67
67
  |---------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
68
68
 
69
69
 
@@ -731,6 +731,28 @@ dynamic_test_table_1 = DynamicTable(
731
731
  - Direct data insertion into Dynamic Tables is not supported.
732
732
 
733
733
 
734
+ ## Verifying Package Signatures
735
+
736
+ To ensure the authenticity and integrity of the Python package, follow the steps below to verify the package signature using `cosign`.
737
+
738
+ **Steps to verify the signature:**
739
+ - Install cosign:
740
+ - This example is using golang installation: [installing-cosign-with-go](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-go)
741
+ - Download the file from the repository like pypi:
742
+ - https://pypi.org/project/snowflake-sqlalchemy/#files
743
+ - Download the signature files from the release tag, replace the version number with the version you are verifying:
744
+ - https://github.com/snowflakedb/snowflake-sqlalchemy/releases/tag/v1.7.3
745
+ - Verify signature:
746
+ ````bash
747
+ # replace the version number with the version you are verifying
748
+ ./cosign verify-blob snowflake_sqlalchemy-1.7.3-py3-none-any.whl \
749
+ --certificate snowflake_sqlalchemy-1.7.3-py3-none-any.whl.crt \
750
+ --certificate-identity https://github.com/snowflakedb/snowflake-sqlalchemy/.github/workflows/python-publish.yml@refs/tags/v1.7.3 \
751
+ --certificate-oidc-issuer https://token.actions.githubusercontent.com \
752
+ --signature snowflake_sqlalchemy-1.7.3-py3-none-any.whl.sig
753
+ Verified OK
754
+ ````
755
+
734
756
  ## Support
735
757
 
736
758
  Feel free to file an issue or submit a PR here for general cases. For official support, contact Snowflake support at:
@@ -9,7 +9,7 @@
9
9
  Snowflake SQLAlchemy runs on the top of the Snowflake Connector for Python as a [dialect](http://docs.sqlalchemy.org/en/latest/dialects/) to bridge a Snowflake database and SQLAlchemy applications.
10
10
 
11
11
 
12
- | :exclamation: | For production-affecting or urgent issues related to the connector, please [create a case with Snowflake Support](https://community.snowflake.com/s/article/How-To-Submit-a-Support-Case-in-Snowflake-Lodge). |
12
+ | :exclamation: | Effective May 8th, 2025, Snowflake SQLAlchemy will transition to maintenance mode and will cease active development. Support will be limited to addressing critical bugs and security vulnerabilities. To report such issues, please [create a case with Snowflake Support](https://community.snowflake.com/s/article/How-To-Submit-a-Support-Case-in-Snowflake-Lodge). for individual evaluation. Please note that pull requests from external contributors may not receive action from Snowflake. |
13
13
  |---------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
14
14
 
15
15
 
@@ -677,6 +677,28 @@ dynamic_test_table_1 = DynamicTable(
677
677
  - Direct data insertion into Dynamic Tables is not supported.
678
678
 
679
679
 
680
+ ## Verifying Package Signatures
681
+
682
+ To ensure the authenticity and integrity of the Python package, follow the steps below to verify the package signature using `cosign`.
683
+
684
+ **Steps to verify the signature:**
685
+ - Install cosign:
686
+ - This example is using golang installation: [installing-cosign-with-go](https://edu.chainguard.dev/open-source/sigstore/cosign/how-to-install-cosign/#installing-cosign-with-go)
687
+ - Download the file from the repository like pypi:
688
+ - https://pypi.org/project/snowflake-sqlalchemy/#files
689
+ - Download the signature files from the release tag, replace the version number with the version you are verifying:
690
+ - https://github.com/snowflakedb/snowflake-sqlalchemy/releases/tag/v1.7.3
691
+ - Verify signature:
692
+ ````bash
693
+ # replace the version number with the version you are verifying
694
+ ./cosign verify-blob snowflake_sqlalchemy-1.7.3-py3-none-any.whl \
695
+ --certificate snowflake_sqlalchemy-1.7.3-py3-none-any.whl.crt \
696
+ --certificate-identity https://github.com/snowflakedb/snowflake-sqlalchemy/.github/workflows/python-publish.yml@refs/tags/v1.7.3 \
697
+ --certificate-oidc-issuer https://token.actions.githubusercontent.com \
698
+ --signature snowflake_sqlalchemy-1.7.3-py3-none-any.whl.sig
699
+ Verified OK
700
+ ````
701
+
680
702
  ## Support
681
703
 
682
704
  Feel free to file an issue or submit a PR here for general cases. For official support, contact Snowflake support at:
@@ -530,9 +530,11 @@ class SnowflakeCompiler(compiler.SQLCompiler):
530
530
  clauses = " ".join(
531
531
  clause._compiler_dispatch(self, **kw) for clause in merge_into.clauses
532
532
  )
533
- return (
534
- f"MERGE INTO {merge_into.target} USING {merge_into.source} ON {merge_into.on}"
535
- + (" " + clauses if clauses else "")
533
+ target = merge_into.target._compiler_dispatch(self, asfrom=True, **kw)
534
+ source = merge_into.source._compiler_dispatch(self, asfrom=True, **kw)
535
+ on = merge_into.on._compiler_dispatch(self, **kw)
536
+ return f"MERGE INTO {target} USING {source} ON {on}" + (
537
+ " " + clauses if clauses else ""
536
538
  )
537
539
 
538
540
  def visit_merge_into_clause(self, merge_into_clause, **kw):
@@ -579,11 +581,8 @@ class SnowflakeCompiler(compiler.SQLCompiler):
579
581
  formatter = copy_into.formatter._compiler_dispatch(self, **kw)
580
582
  else:
581
583
  formatter = ""
582
- into = (
583
- copy_into.into
584
- if isinstance(copy_into.into, Table)
585
- else copy_into.into._compiler_dispatch(self, **kw)
586
- )
584
+ into = copy_into.into._compiler_dispatch(self, asfrom=True, **kw)
585
+ from_ = None
587
586
  if isinstance(copy_into.from_, Table):
588
587
  from_ = copy_into.from_.name
589
588
  # this is intended to catch AWSBucket and AzureContainer
@@ -511,13 +511,6 @@ class SnowflakeDialect(default.DefaultDialect):
511
511
  )
512
512
  schema_name = self.denormalize_name(schema)
513
513
 
514
- iceberg_table_names = self.get_table_names_with_prefix(
515
- connection,
516
- schema=schema_name,
517
- prefix=CustomTablePrefix.ICEBERG.name,
518
- info_cache=kw.get("info_cache", None),
519
- )
520
-
521
514
  result = connection.execute(
522
515
  text(
523
516
  """
@@ -578,10 +571,7 @@ class SnowflakeDialect(default.DefaultDialect):
578
571
  col_type_kw["scale"] = numeric_scale
579
572
  elif issubclass(col_type, (sqltypes.String, sqltypes.BINARY)):
580
573
  col_type_kw["length"] = character_maximum_length
581
- elif (
582
- issubclass(col_type, StructuredType)
583
- and table_name in iceberg_table_names
584
- ):
574
+ elif issubclass(col_type, StructuredType):
585
575
  if (schema_name, table_name) not in full_columns_descriptions:
586
576
  full_columns_descriptions[(schema_name, table_name)] = (
587
577
  self.table_columns_as_dict(
@@ -654,21 +644,13 @@ class SnowflakeDialect(default.DefaultDialect):
654
644
  f" TABLE {table_schema}.{table_name} TYPE = COLUMNS"
655
645
  )
656
646
  )
657
- for (
658
- column_name,
659
- coltype,
660
- _kind,
661
- is_nullable,
662
- column_default,
663
- primary_key,
664
- _unique_key,
665
- _check,
666
- _expression,
667
- comment,
668
- _policy_name,
669
- _privacy_domain,
670
- _name_mapping,
671
- ) in result:
647
+ for desc_data in result:
648
+ column_name = desc_data[0]
649
+ coltype = desc_data[1]
650
+ is_nullable = desc_data[3]
651
+ column_default = desc_data[4]
652
+ primary_key = desc_data[5]
653
+ comment = desc_data[9]
672
654
 
673
655
  column_name = self.normalize_name(column_name)
674
656
  if column_name.startswith("sys_clustering_column"):
@@ -3,4 +3,4 @@
3
3
  #
4
4
  # Update this for the versions
5
5
  # Don't change the forth version number from None
6
- VERSION = "1.7.3"
6
+ VERSION = "1.7.5"
@@ -203,6 +203,12 @@ def get_engine(url: URL, **engine_kwargs):
203
203
  "echo": True,
204
204
  }
205
205
  engine_params.update(engine_kwargs)
206
+
207
+ connect_args = engine_params.get("connect_args", {}).copy()
208
+ connect_args["disable_ocsp_checks"] = True
209
+ connect_args["insecure_mode"] = True
210
+ engine_params["connect_args"] = connect_args
211
+
206
212
  engine = create_engine(url, **engine_params)
207
213
  return engine
208
214
 
@@ -21,6 +21,9 @@
21
21
  }),
22
22
  ])
23
23
  # ---
24
+ # name: test_reflection_of_table_with_object_data_type
25
+ 'CREATE TABLE test_snowflake_table_reflection (\tid DECIMAL(38, 0) NOT NULL, \tname OBJECT, \tCONSTRAINT demo_name PRIMARY KEY (id))'
26
+ # ---
24
27
  # name: test_simple_reflection_of_table_as_snowflake_table
25
28
  'CREATE TABLE test_snowflake_table_reflection (\tid DECIMAL(38, 0) NOT NULL, \tname VARCHAR(16777216), \tCONSTRAINT demo_name PRIMARY KEY (id))'
26
29
  # ---
@@ -9,7 +9,7 @@ from snowflake.sqlalchemy import IcebergTable
9
9
 
10
10
 
11
11
  @pytest.mark.aws
12
- def test_create_iceberg_table(engine_testaccount, snapshot):
12
+ def test_create_iceberg_table(engine_testaccount):
13
13
  metadata = MetaData()
14
14
  external_volume_name = "exvol"
15
15
  create_external_volume = f"""
@@ -19,7 +19,7 @@ def test_create_iceberg_table(engine_testaccount, snapshot):
19
19
  (
20
20
  NAME = 'my-s3-us-west-2'
21
21
  STORAGE_PROVIDER = 'S3'
22
- STORAGE_BASE_URL = 's3://MY_EXAMPLE_BUCKET/'
22
+ STORAGE_BASE_URL = 's3://myexamplebucket/'
23
23
  STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::123456789012:role/myrole'
24
24
  ENCRYPTION=(TYPE='AWS_SSE_KMS' KMS_KEY_ID='1234abcd-12ab-34cd-56ef-1234567890ab')
25
25
  )
@@ -40,4 +40,7 @@ def test_create_iceberg_table(engine_testaccount, snapshot):
40
40
  metadata.create_all(engine_testaccount)
41
41
 
42
42
  error_str = str(argument_error.value)
43
- assert error_str[: error_str.rfind("\n")] == snapshot
43
+ assert (
44
+ "(snowflake.connector.errors.ProgrammingError)"
45
+ in error_str[: error_str.rfind("\n")]
46
+ )
@@ -7,6 +7,36 @@ from sqlalchemy.sql.ddl import CreateTable
7
7
  from snowflake.sqlalchemy import SnowflakeTable
8
8
 
9
9
 
10
+ def test_reflection_of_table_with_object_data_type(
11
+ engine_testaccount, db_parameters, sql_compiler, snapshot
12
+ ):
13
+ metadata = MetaData()
14
+ table_name = "test_snowflake_table_reflection"
15
+
16
+ create_table_sql = f"""
17
+ CREATE TABLE {table_name} (id INT primary key, name OBJECT);
18
+ """
19
+
20
+ with engine_testaccount.connect() as connection:
21
+ connection.exec_driver_sql(create_table_sql)
22
+
23
+ snowflake_test_table = Table(table_name, metadata, autoload_with=engine_testaccount)
24
+ constraint = snowflake_test_table.constraints.pop()
25
+ constraint.name = "demo_name"
26
+ snowflake_test_table.constraints.add(constraint)
27
+
28
+ try:
29
+ with engine_testaccount.connect():
30
+ value = CreateTable(snowflake_test_table)
31
+
32
+ actual = sql_compiler(value)
33
+
34
+ assert actual == snapshot
35
+
36
+ finally:
37
+ metadata.drop_all(engine_testaccount)
38
+
39
+
10
40
  def test_simple_reflection_of_table_as_sqlalchemy_table(
11
41
  engine_testaccount, db_parameters, sql_compiler, snapshot
12
42
  ):
@@ -261,7 +261,7 @@ def test_copy_into_storage_csv_extended(sql_compiler):
261
261
  # check that the result is as expected
262
262
  result = sql_compiler(copy_into)
263
263
  expected = (
264
- r"COPY INTO TEST_IMPORT "
264
+ r'COPY INTO "TEST_IMPORT" '
265
265
  r"FROM @ML_POC.PUBLIC.AZURE_STAGE/testdata "
266
266
  r"FILE_FORMAT=(TYPE=csv COMPRESSION='auto' DATE_FORMAT='AUTO' "
267
267
  r"ERROR_ON_COLUMN_COUNT_MISMATCH=True ESCAPE=None "
@@ -317,7 +317,7 @@ def test_copy_into_storage_parquet_named_format(sql_compiler):
317
317
  # compile and check the result
318
318
  result = sql_compiler(copy_into)
319
319
  expected = (
320
- "COPY INTO TEST_IMPORT "
320
+ 'COPY INTO "TEST_IMPORT" '
321
321
  "FROM (SELECT $1:COL1::number, $1:COL2::varchar "
322
322
  "FROM @ML_POC.PUBLIC.AZURE_STAGE/testdata/out.parquet) "
323
323
  "FILE_FORMAT=(format_name = parquet_file_format) force = TRUE"
@@ -378,7 +378,7 @@ def test_copy_into_storage_parquet_files(sql_compiler):
378
378
  # compile and check the result
379
379
  result = sql_compiler(copy_into)
380
380
  expected = (
381
- "COPY INTO TEST_IMPORT "
381
+ 'COPY INTO "TEST_IMPORT" '
382
382
  "FROM (SELECT $1:COL1::number, $1:COL2::varchar "
383
383
  "FROM @ML_POC.PUBLIC.AZURE_STAGE/testdata/out.parquet "
384
384
  "(file_format => parquet_file_format)) FILES = ('foo.txt','bar.txt') "
@@ -440,7 +440,7 @@ def test_copy_into_storage_parquet_pattern(sql_compiler):
440
440
  # compile and check the result
441
441
  result = sql_compiler(copy_into)
442
442
  expected = (
443
- "COPY INTO TEST_IMPORT "
443
+ 'COPY INTO "TEST_IMPORT" '
444
444
  "FROM (SELECT $1:COL1::number, $1:COL2::varchar "
445
445
  "FROM @ML_POC.PUBLIC.AZURE_STAGE/testdata/out.parquet "
446
446
  "(file_format => parquet_file_format)) FORCE = true PATTERN = '.*csv'"