snowflake-sqlalchemy 1.6.1__tar.gz → 1.7.1__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.
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/.pre-commit-config.yaml +1 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/DESCRIPTION.md +17 -2
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/PKG-INFO +155 -7
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/README.md +152 -4
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/pyproject.toml +5 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/__init__.py +52 -6
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/_constants.py +2 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/base.py +78 -15
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/custom_commands.py +7 -2
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/custom_types.py +20 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/exc.py +82 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/parser/custom_type_parser.py +190 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/snowdialect.py +214 -142
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/__init__.py +9 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/clustered_table.py +37 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/custom_table_base.py +127 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/custom_table_prefix.py +13 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/dynamic_table.py +117 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/hybrid_table.py +62 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/iceberg_table.py +102 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/__init__.py +33 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/as_query_option.py +63 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/cluster_by_option.py +58 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/identifier_option.py +63 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/invalid_table_option.py +25 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/keyword_option.py +65 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/keywords.py +14 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/literal_option.py +67 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/table_option.py +84 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/options/target_lag_option.py +94 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/snowflake_table.py +70 -0
- snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql/custom_schema/table_from_query.py +54 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/version.py +1 -1
- snowflake_sqlalchemy-1.7.1/tests/__snapshots__/test_compile_dynamic_table.ambr +13 -0
- snowflake_sqlalchemy-1.7.1/tests/__snapshots__/test_core.ambr +4 -0
- snowflake_sqlalchemy-1.7.1/tests/__snapshots__/test_orm.ambr +4 -0
- snowflake_sqlalchemy-1.7.1/tests/__snapshots__/test_reflect_dynamic_table.ambr +4 -0
- snowflake_sqlalchemy-1.7.1/tests/__snapshots__/test_structured_datatypes.ambr +90 -0
- snowflake_sqlalchemy-1.7.1/tests/__snapshots__/test_unit_structured_types.ambr +4 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/conftest.py +30 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__init__.py +2 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_compile_dynamic_table.ambr +40 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_compile_hybrid_table.ambr +7 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_compile_iceberg_table.ambr +19 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_compile_snowflake_table.ambr +35 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_create_dynamic_table.ambr +7 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_create_hybrid_table.ambr +7 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_create_iceberg_table.ambr +14 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_create_snowflake_table.ambr +4 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_generic_options.ambr +13 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_reflect_hybrid_table.ambr +4 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/__snapshots__/test_reflect_snowflake_table.ambr +29 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_compile_dynamic_table.py +271 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_compile_hybrid_table.py +52 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_compile_iceberg_table.py +116 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_compile_snowflake_table.py +180 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_create_dynamic_table.py +124 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_create_hybrid_table.py +95 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_create_iceberg_table.py +43 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_create_snowflake_table.py +66 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_generic_options.py +83 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_reflect_dynamic_table.py +88 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_reflect_hybrid_table.py +65 -0
- snowflake_sqlalchemy-1.7.1/tests/custom_tables/test_reflect_snowflake_table.py +92 -0
- snowflake_sqlalchemy-1.7.1/tests/sqlalchemy_test_suite/__init__.py +3 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_copy.py +48 -17
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_core.py +89 -89
- snowflake_sqlalchemy-1.7.1/tests/test_custom_types.py +67 -0
- snowflake_sqlalchemy-1.7.1/tests/test_imports.py +64 -0
- snowflake_sqlalchemy-1.7.1/tests/test_index_reflection.py +34 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_orm.py +178 -9
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_pandas.py +1 -1
- snowflake_sqlalchemy-1.7.1/tests/test_structured_datatypes.py +271 -0
- snowflake_sqlalchemy-1.7.1/tests/test_unit_structured_types.py +73 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/util.py +2 -0
- snowflake_sqlalchemy-1.6.1/tests/test_custom_types.py +0 -36
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/.gitignore +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/.gitmodules +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/LICENSE.txt +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/MANIFEST.in +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/build.sh +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/build_docker.sh +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/docker/sqlalchemy_build/Dockerfile +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/docker/sqlalchemy_build/scripts/entrypoint.sh +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/set_base_image.sh +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/test.sh +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/test_docker.sh +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/ci/test_linux.sh +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/license_header.txt +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/setup.cfg +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/snyk/requirements.txt +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/snyk/requiremtnts.txt +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/snyk/update_requirements.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/compat.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/functions.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/provision.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/requirements.py +0 -0
- {snowflake_sqlalchemy-1.6.1/tests → snowflake_sqlalchemy-1.7.1/src/snowflake/sqlalchemy/sql}/__init__.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/util.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tested_requirements/requirements_310.reqs +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tested_requirements/requirements_37.reqs +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tested_requirements/requirements_38.reqs +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tested_requirements/requirements_39.reqs +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/README.rst +0 -0
- {snowflake_sqlalchemy-1.6.1/tests/sqlalchemy_test_suite → snowflake_sqlalchemy-1.7.1/tests}/__init__.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/data/users.txt +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/sqlalchemy_test_suite/README.md +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/sqlalchemy_test_suite/conftest.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/sqlalchemy_test_suite/test_suite.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/sqlalchemy_test_suite/test_suite_20.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_compiler.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_create.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_custom_functions.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_geography.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_geometry.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_multivalues_insert.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_qmark.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_quote.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_semi_structured_datatypes.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_sequence.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_timestamp.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_unit_core.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_unit_cte.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_unit_types.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tests/test_unit_url.py +0 -0
- {snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/tox.ini +0 -0
|
@@ -9,6 +9,21 @@ Source code is also available at:
|
|
|
9
9
|
|
|
10
10
|
# Release Notes
|
|
11
11
|
|
|
12
|
+
- v1.7.1(December 02, 2024)
|
|
13
|
+
- Add support for partition by to copy into <location>
|
|
14
|
+
- Fix BOOLEAN type not found in snowdialect
|
|
15
|
+
|
|
16
|
+
- v1.7.0(November 21, 2024)
|
|
17
|
+
|
|
18
|
+
- Add support for dynamic tables and required options
|
|
19
|
+
- Add support for hybrid tables
|
|
20
|
+
- Fixed SAWarning when registering functions with existing name in default namespace
|
|
21
|
+
- Update options to be defined in key arguments instead of arguments.
|
|
22
|
+
- Add support for refresh_mode option in DynamicTable
|
|
23
|
+
- Add support for iceberg table with Snowflake Catalog
|
|
24
|
+
- Fix cluster by option to support explicit expressions
|
|
25
|
+
- Add support for MAP datatype
|
|
26
|
+
|
|
12
27
|
- v1.6.1(July 9, 2024)
|
|
13
28
|
|
|
14
29
|
- Update internal project workflow with pypi publishing
|
|
@@ -24,7 +39,7 @@ Source code is also available at:
|
|
|
24
39
|
|
|
25
40
|
- v1.5.3(April 16, 2024)
|
|
26
41
|
|
|
27
|
-
|
|
42
|
+
- Limit SQLAlchemy to < 2.0.0 before releasing version compatible with 2.0
|
|
28
43
|
|
|
29
44
|
- v1.5.2(April 11, 2024)
|
|
30
45
|
|
|
@@ -33,7 +48,7 @@ Source code is also available at:
|
|
|
33
48
|
|
|
34
49
|
- v1.5.1(November 03, 2023)
|
|
35
50
|
|
|
36
|
-
- Fixed a compatibility issue with Snowflake Behavioral Change 1057 on outer lateral join, for more details check https://docs.snowflake.com/en/release-notes/bcr-bundles/2023_04/bcr-1057
|
|
51
|
+
- Fixed a compatibility issue with Snowflake Behavioral Change 1057 on outer lateral join, for more details check <https://docs.snowflake.com/en/release-notes/bcr-bundles/2023_04/bcr-1057>.
|
|
37
52
|
- Fixed credentials with `externalbrowser` authentication not caching due to incorrect parsing of boolean query parameters.
|
|
38
53
|
- This fixes other boolean parameter passing to driver as well.
|
|
39
54
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: snowflake-sqlalchemy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.1
|
|
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
|
|
@@ -8,8 +8,7 @@ Project-URL: Homepage, https://www.snowflake.com/
|
|
|
8
8
|
Project-URL: Issues, https://github.com/snowflakedb/snowflake-sqlalchemy/issues
|
|
9
9
|
Project-URL: Source, https://github.com/snowflakedb/snowflake-sqlalchemy
|
|
10
10
|
Author-email: "Snowflake Inc." <triage-snowpark-python-api-dl@snowflake.com>
|
|
11
|
-
License
|
|
12
|
-
License-File: LICENSE.txt
|
|
11
|
+
License: Apache-2.0
|
|
13
12
|
Keywords: Snowflake,analytics,cloud,database,db,warehouse
|
|
14
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
15
14
|
Classifier: Environment :: Console
|
|
@@ -46,6 +45,7 @@ Requires-Dist: pytest-cov; extra == 'development'
|
|
|
46
45
|
Requires-Dist: pytest-rerunfailures; extra == 'development'
|
|
47
46
|
Requires-Dist: pytest-timeout; extra == 'development'
|
|
48
47
|
Requires-Dist: pytz; extra == 'development'
|
|
48
|
+
Requires-Dist: syrupy==4.6.1; extra == 'development'
|
|
49
49
|
Provides-Extra: pandas
|
|
50
50
|
Requires-Dist: snowflake-connector-python[pandas]; extra == 'pandas'
|
|
51
51
|
Description-Content-Type: text/markdown
|
|
@@ -60,6 +60,11 @@ Description-Content-Type: text/markdown
|
|
|
60
60
|
|
|
61
61
|
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.
|
|
62
62
|
|
|
63
|
+
|
|
64
|
+
| :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). |
|
|
65
|
+
|---------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
66
|
+
|
|
67
|
+
|
|
63
68
|
## Prerequisites
|
|
64
69
|
|
|
65
70
|
### Snowflake Connector for Python
|
|
@@ -256,7 +261,7 @@ finally:
|
|
|
256
261
|
|
|
257
262
|
# Best
|
|
258
263
|
try:
|
|
259
|
-
with engine.
|
|
264
|
+
with engine.connect() as connection:
|
|
260
265
|
connection.execute(text(<SQL>))
|
|
261
266
|
# or
|
|
262
267
|
connection.exec_driver_sql(<SQL>)
|
|
@@ -277,11 +282,43 @@ t = Table('mytable', metadata,
|
|
|
277
282
|
|
|
278
283
|
### Object Name Case Handling
|
|
279
284
|
|
|
280
|
-
Snowflake stores all case-insensitive object names in uppercase text. In contrast, SQLAlchemy considers all lowercase object names to be case-insensitive. Snowflake SQLAlchemy converts the object name case during schema-level communication, i.e. during table and index reflection. If you use uppercase object names, SQLAlchemy assumes they are case-sensitive and encloses the names with quotes. This behavior will cause mismatches
|
|
285
|
+
Snowflake stores all case-insensitive object names in uppercase text. In contrast, SQLAlchemy considers all lowercase object names to be case-insensitive. Snowflake SQLAlchemy converts the object name case during schema-level communication, i.e. during table and index reflection. If you use uppercase object names, SQLAlchemy assumes they are case-sensitive and encloses the names with quotes. This behavior will cause mismatches against data dictionary data received from Snowflake, so unless identifier names have been truly created as case sensitive using quotes, e.g., `"TestDb"`, all lowercase names should be used on the SQLAlchemy side.
|
|
281
286
|
|
|
282
287
|
### Index Support
|
|
283
288
|
|
|
284
|
-
|
|
289
|
+
Indexes are supported only for Hybrid Tables in Snowflake SQLAlchemy. For more details on limitations and use cases, refer to the [Create Index documentation](https://docs.snowflake.com/en/sql-reference/constraints-indexes.html). You can create an index using the following methods:
|
|
290
|
+
|
|
291
|
+
#### Single Column Index
|
|
292
|
+
|
|
293
|
+
You can create a single column index by setting the `index=True` parameter on the column or by explicitly defining an `Index` object.
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
hybrid_test_table_1 = HybridTable(
|
|
297
|
+
"table_name",
|
|
298
|
+
metadata,
|
|
299
|
+
Column("column1", Integer, primary_key=True),
|
|
300
|
+
Column("column2", String, index=True),
|
|
301
|
+
Index("index_1", "column1", "column2")
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
metadata.create_all(engine_testaccount)
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
#### Multi-Column Index
|
|
308
|
+
|
|
309
|
+
For multi-column indexes, you define the `Index` object specifying the columns that should be indexed.
|
|
310
|
+
|
|
311
|
+
```python
|
|
312
|
+
hybrid_test_table_1 = HybridTable(
|
|
313
|
+
"table_name",
|
|
314
|
+
metadata,
|
|
315
|
+
Column("column1", Integer, primary_key=True),
|
|
316
|
+
Column("column2", String),
|
|
317
|
+
Index("index_1", "column1", "column2")
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
metadata.create_all(engine_testaccount)
|
|
321
|
+
```
|
|
285
322
|
|
|
286
323
|
### Numpy Data Type Support
|
|
287
324
|
|
|
@@ -392,7 +429,7 @@ This example shows how to create a table with two columns, `id` and `name`, as t
|
|
|
392
429
|
t = Table('myuser', metadata,
|
|
393
430
|
Column('id', Integer, primary_key=True),
|
|
394
431
|
Column('name', String),
|
|
395
|
-
snowflake_clusterby=['id', 'name'], ...
|
|
432
|
+
snowflake_clusterby=['id', 'name', text('id > 5')], ...
|
|
396
433
|
)
|
|
397
434
|
metadata.create_all(engine)
|
|
398
435
|
```
|
|
@@ -508,6 +545,117 @@ copy_into = CopyIntoStorage(from_=users,
|
|
|
508
545
|
connection.execute(copy_into)
|
|
509
546
|
```
|
|
510
547
|
|
|
548
|
+
### Iceberg Table with Snowflake Catalog support
|
|
549
|
+
|
|
550
|
+
Snowflake SQLAlchemy supports Iceberg Tables with the Snowflake Catalog, along with various related parameters. For detailed information about Iceberg Tables, refer to the Snowflake [CREATE ICEBERG](https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table-snowflake) documentation.
|
|
551
|
+
|
|
552
|
+
To create an Iceberg Table using Snowflake SQLAlchemy, you can define the table using the SQLAlchemy Core syntax as follows:
|
|
553
|
+
|
|
554
|
+
```python
|
|
555
|
+
table = IcebergTable(
|
|
556
|
+
"myuser",
|
|
557
|
+
metadata,
|
|
558
|
+
Column("id", Integer, primary_key=True),
|
|
559
|
+
Column("name", String),
|
|
560
|
+
external_volume=external_volume_name,
|
|
561
|
+
base_location="my_iceberg_table",
|
|
562
|
+
as_query="SELECT * FROM table"
|
|
563
|
+
)
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
Alternatively, you can define the table using a declarative approach:
|
|
567
|
+
|
|
568
|
+
```python
|
|
569
|
+
class MyUser(Base):
|
|
570
|
+
__tablename__ = "myuser"
|
|
571
|
+
|
|
572
|
+
@classmethod
|
|
573
|
+
def __table_cls__(cls, name, metadata, *arg, **kw):
|
|
574
|
+
return IcebergTable(name, metadata, *arg, **kw)
|
|
575
|
+
|
|
576
|
+
__table_args__ = {
|
|
577
|
+
"external_volume": "my_external_volume",
|
|
578
|
+
"base_location": "my_iceberg_table",
|
|
579
|
+
"as_query": "SELECT * FROM table",
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
id = Column(Integer, primary_key=True)
|
|
583
|
+
name = Column(String)
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
### Hybrid Table support
|
|
587
|
+
|
|
588
|
+
Snowflake SQLAlchemy supports Hybrid Tables with indexes. For detailed information, refer to the Snowflake [CREATE HYBRID TABLE](https://docs.snowflake.com/en/sql-reference/sql/create-hybrid-table) documentation.
|
|
589
|
+
|
|
590
|
+
To create a Hybrid Table and add an index, you can use the SQLAlchemy Core syntax as follows:
|
|
591
|
+
|
|
592
|
+
```python
|
|
593
|
+
table = HybridTable(
|
|
594
|
+
"myuser",
|
|
595
|
+
metadata,
|
|
596
|
+
Column("id", Integer, primary_key=True),
|
|
597
|
+
Column("name", String),
|
|
598
|
+
Index("idx_name", "name")
|
|
599
|
+
)
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
Alternatively, you can define the table using the declarative approach:
|
|
603
|
+
|
|
604
|
+
```python
|
|
605
|
+
class MyUser(Base):
|
|
606
|
+
__tablename__ = "myuser"
|
|
607
|
+
|
|
608
|
+
@classmethod
|
|
609
|
+
def __table_cls__(cls, name, metadata, *arg, **kw):
|
|
610
|
+
return HybridTable(name, metadata, *arg, **kw)
|
|
611
|
+
|
|
612
|
+
__table_args__ = (
|
|
613
|
+
Index("idx_name", "name"),
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
id = Column(Integer, primary_key=True)
|
|
617
|
+
name = Column(String)
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### Dynamic Tables support
|
|
621
|
+
|
|
622
|
+
Snowflake SQLAlchemy supports Dynamic Tables. For detailed information, refer to the Snowflake [CREATE DYNAMIC TABLE](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table) documentation.
|
|
623
|
+
|
|
624
|
+
To create a Dynamic Table, you can use the SQLAlchemy Core syntax as follows:
|
|
625
|
+
|
|
626
|
+
```python
|
|
627
|
+
dynamic_test_table_1 = DynamicTable(
|
|
628
|
+
"dynamic_MyUser",
|
|
629
|
+
metadata,
|
|
630
|
+
Column("id", Integer),
|
|
631
|
+
Column("name", String),
|
|
632
|
+
target_lag=(1, TimeUnit.HOURS), # Additionally, you can use SnowflakeKeyword.DOWNSTREAM
|
|
633
|
+
warehouse='test_wh',
|
|
634
|
+
refresh_mode=SnowflakeKeyword.FULL,
|
|
635
|
+
as_query="SELECT id, name from MyUser;"
|
|
636
|
+
)
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
Alternatively, you can define a table without columns using the SQLAlchemy `select()` construct:
|
|
640
|
+
|
|
641
|
+
```python
|
|
642
|
+
dynamic_test_table_1 = DynamicTable(
|
|
643
|
+
"dynamic_MyUser",
|
|
644
|
+
metadata,
|
|
645
|
+
target_lag=(1, TimeUnit.HOURS),
|
|
646
|
+
warehouse='test_wh',
|
|
647
|
+
refresh_mode=SnowflakeKeyword.FULL,
|
|
648
|
+
as_query=select(MyUser.id, MyUser.name)
|
|
649
|
+
)
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
### Notes
|
|
653
|
+
|
|
654
|
+
- Defining a primary key in a Dynamic Table is not supported, meaning declarative tables don’t support Dynamic Tables.
|
|
655
|
+
- When using the `as_query` parameter with a string, you must explicitly define the columns. However, if you use the SQLAlchemy `select()` construct, you don’t need to explicitly define the columns.
|
|
656
|
+
- Direct data insertion into Dynamic Tables is not supported.
|
|
657
|
+
|
|
658
|
+
|
|
511
659
|
## Support
|
|
512
660
|
|
|
513
661
|
Feel free to file an issue or submit a PR here for general cases. For official support, contact Snowflake support at:
|
|
@@ -8,6 +8,11 @@
|
|
|
8
8
|
|
|
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
|
+
|
|
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). |
|
|
13
|
+
|---------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
14
|
+
|
|
15
|
+
|
|
11
16
|
## Prerequisites
|
|
12
17
|
|
|
13
18
|
### Snowflake Connector for Python
|
|
@@ -204,7 +209,7 @@ finally:
|
|
|
204
209
|
|
|
205
210
|
# Best
|
|
206
211
|
try:
|
|
207
|
-
with engine.
|
|
212
|
+
with engine.connect() as connection:
|
|
208
213
|
connection.execute(text(<SQL>))
|
|
209
214
|
# or
|
|
210
215
|
connection.exec_driver_sql(<SQL>)
|
|
@@ -225,11 +230,43 @@ t = Table('mytable', metadata,
|
|
|
225
230
|
|
|
226
231
|
### Object Name Case Handling
|
|
227
232
|
|
|
228
|
-
Snowflake stores all case-insensitive object names in uppercase text. In contrast, SQLAlchemy considers all lowercase object names to be case-insensitive. Snowflake SQLAlchemy converts the object name case during schema-level communication, i.e. during table and index reflection. If you use uppercase object names, SQLAlchemy assumes they are case-sensitive and encloses the names with quotes. This behavior will cause mismatches
|
|
233
|
+
Snowflake stores all case-insensitive object names in uppercase text. In contrast, SQLAlchemy considers all lowercase object names to be case-insensitive. Snowflake SQLAlchemy converts the object name case during schema-level communication, i.e. during table and index reflection. If you use uppercase object names, SQLAlchemy assumes they are case-sensitive and encloses the names with quotes. This behavior will cause mismatches against data dictionary data received from Snowflake, so unless identifier names have been truly created as case sensitive using quotes, e.g., `"TestDb"`, all lowercase names should be used on the SQLAlchemy side.
|
|
229
234
|
|
|
230
235
|
### Index Support
|
|
231
236
|
|
|
232
|
-
|
|
237
|
+
Indexes are supported only for Hybrid Tables in Snowflake SQLAlchemy. For more details on limitations and use cases, refer to the [Create Index documentation](https://docs.snowflake.com/en/sql-reference/constraints-indexes.html). You can create an index using the following methods:
|
|
238
|
+
|
|
239
|
+
#### Single Column Index
|
|
240
|
+
|
|
241
|
+
You can create a single column index by setting the `index=True` parameter on the column or by explicitly defining an `Index` object.
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
hybrid_test_table_1 = HybridTable(
|
|
245
|
+
"table_name",
|
|
246
|
+
metadata,
|
|
247
|
+
Column("column1", Integer, primary_key=True),
|
|
248
|
+
Column("column2", String, index=True),
|
|
249
|
+
Index("index_1", "column1", "column2")
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
metadata.create_all(engine_testaccount)
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
#### Multi-Column Index
|
|
256
|
+
|
|
257
|
+
For multi-column indexes, you define the `Index` object specifying the columns that should be indexed.
|
|
258
|
+
|
|
259
|
+
```python
|
|
260
|
+
hybrid_test_table_1 = HybridTable(
|
|
261
|
+
"table_name",
|
|
262
|
+
metadata,
|
|
263
|
+
Column("column1", Integer, primary_key=True),
|
|
264
|
+
Column("column2", String),
|
|
265
|
+
Index("index_1", "column1", "column2")
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
metadata.create_all(engine_testaccount)
|
|
269
|
+
```
|
|
233
270
|
|
|
234
271
|
### Numpy Data Type Support
|
|
235
272
|
|
|
@@ -340,7 +377,7 @@ This example shows how to create a table with two columns, `id` and `name`, as t
|
|
|
340
377
|
t = Table('myuser', metadata,
|
|
341
378
|
Column('id', Integer, primary_key=True),
|
|
342
379
|
Column('name', String),
|
|
343
|
-
snowflake_clusterby=['id', 'name'], ...
|
|
380
|
+
snowflake_clusterby=['id', 'name', text('id > 5')], ...
|
|
344
381
|
)
|
|
345
382
|
metadata.create_all(engine)
|
|
346
383
|
```
|
|
@@ -456,6 +493,117 @@ copy_into = CopyIntoStorage(from_=users,
|
|
|
456
493
|
connection.execute(copy_into)
|
|
457
494
|
```
|
|
458
495
|
|
|
496
|
+
### Iceberg Table with Snowflake Catalog support
|
|
497
|
+
|
|
498
|
+
Snowflake SQLAlchemy supports Iceberg Tables with the Snowflake Catalog, along with various related parameters. For detailed information about Iceberg Tables, refer to the Snowflake [CREATE ICEBERG](https://docs.snowflake.com/en/sql-reference/sql/create-iceberg-table-snowflake) documentation.
|
|
499
|
+
|
|
500
|
+
To create an Iceberg Table using Snowflake SQLAlchemy, you can define the table using the SQLAlchemy Core syntax as follows:
|
|
501
|
+
|
|
502
|
+
```python
|
|
503
|
+
table = IcebergTable(
|
|
504
|
+
"myuser",
|
|
505
|
+
metadata,
|
|
506
|
+
Column("id", Integer, primary_key=True),
|
|
507
|
+
Column("name", String),
|
|
508
|
+
external_volume=external_volume_name,
|
|
509
|
+
base_location="my_iceberg_table",
|
|
510
|
+
as_query="SELECT * FROM table"
|
|
511
|
+
)
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
Alternatively, you can define the table using a declarative approach:
|
|
515
|
+
|
|
516
|
+
```python
|
|
517
|
+
class MyUser(Base):
|
|
518
|
+
__tablename__ = "myuser"
|
|
519
|
+
|
|
520
|
+
@classmethod
|
|
521
|
+
def __table_cls__(cls, name, metadata, *arg, **kw):
|
|
522
|
+
return IcebergTable(name, metadata, *arg, **kw)
|
|
523
|
+
|
|
524
|
+
__table_args__ = {
|
|
525
|
+
"external_volume": "my_external_volume",
|
|
526
|
+
"base_location": "my_iceberg_table",
|
|
527
|
+
"as_query": "SELECT * FROM table",
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
id = Column(Integer, primary_key=True)
|
|
531
|
+
name = Column(String)
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Hybrid Table support
|
|
535
|
+
|
|
536
|
+
Snowflake SQLAlchemy supports Hybrid Tables with indexes. For detailed information, refer to the Snowflake [CREATE HYBRID TABLE](https://docs.snowflake.com/en/sql-reference/sql/create-hybrid-table) documentation.
|
|
537
|
+
|
|
538
|
+
To create a Hybrid Table and add an index, you can use the SQLAlchemy Core syntax as follows:
|
|
539
|
+
|
|
540
|
+
```python
|
|
541
|
+
table = HybridTable(
|
|
542
|
+
"myuser",
|
|
543
|
+
metadata,
|
|
544
|
+
Column("id", Integer, primary_key=True),
|
|
545
|
+
Column("name", String),
|
|
546
|
+
Index("idx_name", "name")
|
|
547
|
+
)
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
Alternatively, you can define the table using the declarative approach:
|
|
551
|
+
|
|
552
|
+
```python
|
|
553
|
+
class MyUser(Base):
|
|
554
|
+
__tablename__ = "myuser"
|
|
555
|
+
|
|
556
|
+
@classmethod
|
|
557
|
+
def __table_cls__(cls, name, metadata, *arg, **kw):
|
|
558
|
+
return HybridTable(name, metadata, *arg, **kw)
|
|
559
|
+
|
|
560
|
+
__table_args__ = (
|
|
561
|
+
Index("idx_name", "name"),
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
id = Column(Integer, primary_key=True)
|
|
565
|
+
name = Column(String)
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Dynamic Tables support
|
|
569
|
+
|
|
570
|
+
Snowflake SQLAlchemy supports Dynamic Tables. For detailed information, refer to the Snowflake [CREATE DYNAMIC TABLE](https://docs.snowflake.com/en/sql-reference/sql/create-dynamic-table) documentation.
|
|
571
|
+
|
|
572
|
+
To create a Dynamic Table, you can use the SQLAlchemy Core syntax as follows:
|
|
573
|
+
|
|
574
|
+
```python
|
|
575
|
+
dynamic_test_table_1 = DynamicTable(
|
|
576
|
+
"dynamic_MyUser",
|
|
577
|
+
metadata,
|
|
578
|
+
Column("id", Integer),
|
|
579
|
+
Column("name", String),
|
|
580
|
+
target_lag=(1, TimeUnit.HOURS), # Additionally, you can use SnowflakeKeyword.DOWNSTREAM
|
|
581
|
+
warehouse='test_wh',
|
|
582
|
+
refresh_mode=SnowflakeKeyword.FULL,
|
|
583
|
+
as_query="SELECT id, name from MyUser;"
|
|
584
|
+
)
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
Alternatively, you can define a table without columns using the SQLAlchemy `select()` construct:
|
|
588
|
+
|
|
589
|
+
```python
|
|
590
|
+
dynamic_test_table_1 = DynamicTable(
|
|
591
|
+
"dynamic_MyUser",
|
|
592
|
+
metadata,
|
|
593
|
+
target_lag=(1, TimeUnit.HOURS),
|
|
594
|
+
warehouse='test_wh',
|
|
595
|
+
refresh_mode=SnowflakeKeyword.FULL,
|
|
596
|
+
as_query=select(MyUser.id, MyUser.name)
|
|
597
|
+
)
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Notes
|
|
601
|
+
|
|
602
|
+
- Defining a primary key in a Dynamic Table is not supported, meaning declarative tables don’t support Dynamic Tables.
|
|
603
|
+
- When using the `as_query` parameter with a string, you must explicitly define the columns. However, if you use the SQLAlchemy `select()` construct, you don’t need to explicitly define the columns.
|
|
604
|
+
- Direct data insertion into Dynamic Tables is not supported.
|
|
605
|
+
|
|
606
|
+
|
|
459
607
|
## Support
|
|
460
608
|
|
|
461
609
|
Feel free to file an issue or submit a PR here for general cases. For official support, contact Snowflake support at:
|
|
@@ -53,6 +53,7 @@ development = [
|
|
|
53
53
|
"pytz",
|
|
54
54
|
"numpy",
|
|
55
55
|
"mock",
|
|
56
|
+
"syrupy==4.6.1",
|
|
56
57
|
]
|
|
57
58
|
pandas = ["snowflake-connector-python[pandas]"]
|
|
58
59
|
|
|
@@ -91,6 +92,7 @@ SQLACHEMY_WARN_20 = "1"
|
|
|
91
92
|
check = "pre-commit run --all-files"
|
|
92
93
|
test-dialect = "pytest -ra -vvv --tb=short --cov snowflake.sqlalchemy --cov-append --junitxml ./junit.xml --ignore=tests/sqlalchemy_test_suite tests/"
|
|
93
94
|
test-dialect-compatibility = "pytest -ra -vvv --tb=short --cov snowflake.sqlalchemy --cov-append --junitxml ./junit.xml tests/sqlalchemy_test_suite"
|
|
95
|
+
test-dialect-aws = "pytest -m \"aws\" -ra -vvv --tb=short --cov snowflake.sqlalchemy --cov-append --junitxml ./junit.xml --ignore=tests/sqlalchemy_test_suite tests/"
|
|
94
96
|
gh-cache-sum = "python -VV | sha256sum | cut -d' ' -f1"
|
|
95
97
|
check-import = "python -c 'import snowflake.sqlalchemy; print(snowflake.sqlalchemy.__version__)'"
|
|
96
98
|
|
|
@@ -109,6 +111,7 @@ line-length = 88
|
|
|
109
111
|
line-length = 88
|
|
110
112
|
|
|
111
113
|
[tool.pytest.ini_options]
|
|
114
|
+
addopts = "-m 'not feature_max_lob_size and not aws and not requires_external_volume'"
|
|
112
115
|
markers = [
|
|
113
116
|
# Optional dependency groups markers
|
|
114
117
|
"lambda: AWS lambda tests",
|
|
@@ -125,5 +128,7 @@ markers = [
|
|
|
125
128
|
# Other markers
|
|
126
129
|
"timeout: tests that need a timeout time",
|
|
127
130
|
"internal: tests that could but should only run on our internal CI",
|
|
131
|
+
"requires_external_volume: tests that needs a external volume to be executed",
|
|
128
132
|
"external: tests that could but should only run on our external CI",
|
|
133
|
+
"feature_max_lob_size: tests that could but should only run on our external CI",
|
|
129
134
|
]
|
{snowflake_sqlalchemy-1.6.1 → snowflake_sqlalchemy-1.7.1}/src/snowflake/sqlalchemy/__init__.py
RENAMED
|
@@ -9,7 +9,7 @@ if sys.version_info < (3, 8):
|
|
|
9
9
|
else:
|
|
10
10
|
import importlib.metadata as importlib_metadata
|
|
11
11
|
|
|
12
|
-
from sqlalchemy.types import (
|
|
12
|
+
from sqlalchemy.types import ( # noqa
|
|
13
13
|
BIGINT,
|
|
14
14
|
BINARY,
|
|
15
15
|
BOOLEAN,
|
|
@@ -27,8 +27,8 @@ from sqlalchemy.types import (
|
|
|
27
27
|
VARCHAR,
|
|
28
28
|
)
|
|
29
29
|
|
|
30
|
-
from . import base, snowdialect
|
|
31
|
-
from .custom_commands import (
|
|
30
|
+
from . import base, snowdialect # noqa
|
|
31
|
+
from .custom_commands import ( # noqa
|
|
32
32
|
AWSBucket,
|
|
33
33
|
AzureContainer,
|
|
34
34
|
CopyFormatter,
|
|
@@ -41,7 +41,7 @@ from .custom_commands import (
|
|
|
41
41
|
MergeInto,
|
|
42
42
|
PARQUETFormatter,
|
|
43
43
|
)
|
|
44
|
-
from .custom_types import (
|
|
44
|
+
from .custom_types import ( # noqa
|
|
45
45
|
ARRAY,
|
|
46
46
|
BYTEINT,
|
|
47
47
|
CHARACTER,
|
|
@@ -50,6 +50,7 @@ from .custom_types import (
|
|
|
50
50
|
FIXED,
|
|
51
51
|
GEOGRAPHY,
|
|
52
52
|
GEOMETRY,
|
|
53
|
+
MAP,
|
|
53
54
|
NUMBER,
|
|
54
55
|
OBJECT,
|
|
55
56
|
STRING,
|
|
@@ -61,13 +62,30 @@ from .custom_types import (
|
|
|
61
62
|
VARBINARY,
|
|
62
63
|
VARIANT,
|
|
63
64
|
)
|
|
64
|
-
from .
|
|
65
|
+
from .sql.custom_schema import ( # noqa
|
|
66
|
+
DynamicTable,
|
|
67
|
+
HybridTable,
|
|
68
|
+
IcebergTable,
|
|
69
|
+
SnowflakeTable,
|
|
70
|
+
)
|
|
71
|
+
from .sql.custom_schema.options import ( # noqa
|
|
72
|
+
AsQueryOption,
|
|
73
|
+
ClusterByOption,
|
|
74
|
+
IdentifierOption,
|
|
75
|
+
KeywordOption,
|
|
76
|
+
LiteralOption,
|
|
77
|
+
SnowflakeKeyword,
|
|
78
|
+
TableOptionKey,
|
|
79
|
+
TargetLagOption,
|
|
80
|
+
TimeUnit,
|
|
81
|
+
)
|
|
82
|
+
from .util import _url as URL # noqa
|
|
65
83
|
|
|
66
84
|
base.dialect = dialect = snowdialect.dialect
|
|
67
85
|
|
|
68
86
|
__version__ = importlib_metadata.version("snowflake-sqlalchemy")
|
|
69
87
|
|
|
70
|
-
|
|
88
|
+
_custom_types = (
|
|
71
89
|
"BIGINT",
|
|
72
90
|
"BINARY",
|
|
73
91
|
"BOOLEAN",
|
|
@@ -102,6 +120,10 @@ __all__ = (
|
|
|
102
120
|
"TINYINT",
|
|
103
121
|
"VARBINARY",
|
|
104
122
|
"VARIANT",
|
|
123
|
+
"MAP",
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
_custom_commands = (
|
|
105
127
|
"MergeInto",
|
|
106
128
|
"CSVFormatter",
|
|
107
129
|
"JSONFormatter",
|
|
@@ -114,3 +136,27 @@ __all__ = (
|
|
|
114
136
|
"CreateStage",
|
|
115
137
|
"CreateFileFormat",
|
|
116
138
|
)
|
|
139
|
+
|
|
140
|
+
_custom_tables = ("HybridTable", "DynamicTable", "IcebergTable", "SnowflakeTable")
|
|
141
|
+
|
|
142
|
+
_custom_table_options = (
|
|
143
|
+
"AsQueryOption",
|
|
144
|
+
"TargetLagOption",
|
|
145
|
+
"LiteralOption",
|
|
146
|
+
"IdentifierOption",
|
|
147
|
+
"KeywordOption",
|
|
148
|
+
"ClusterByOption",
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
_enums = (
|
|
152
|
+
"TimeUnit",
|
|
153
|
+
"TableOptionKey",
|
|
154
|
+
"SnowflakeKeyword",
|
|
155
|
+
)
|
|
156
|
+
__all__ = (
|
|
157
|
+
*_custom_types,
|
|
158
|
+
*_custom_commands,
|
|
159
|
+
*_custom_tables,
|
|
160
|
+
*_custom_table_options,
|
|
161
|
+
*_enums,
|
|
162
|
+
)
|