sqlframe 1.13.0__tar.gz → 2.0.0__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.
- {sqlframe-1.13.0 → sqlframe-2.0.0}/Makefile +3 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/PKG-INFO +6 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/README.md +5 -1
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/bigquery.md +1 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/configuration.md +30 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/duckdb.md +4 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/postgres.md +4 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/snowflake.md +4 -1
- {sqlframe-1.13.0 → sqlframe-2.0.0}/setup.py +8 -8
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/_version.py +2 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/catalog.py +36 -13
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/column.py +11 -9
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/dataframe.py +72 -79
- sqlframe-2.0.0/sqlframe/base/decorators.py +15 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/function_alternatives.py +127 -12
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/functions.py +99 -27
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/mixins/catalog_mixins.py +156 -45
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/mixins/dataframe_mixins.py +1 -1
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/readerwriter.py +12 -14
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/session.py +167 -41
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/util.py +71 -16
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/catalog.py +79 -28
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/functions.py +8 -8
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/session.py +1 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/catalog.py +30 -13
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/dataframe.py +5 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/functions.py +6 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/readwriter.py +7 -6
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/session.py +5 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/catalog.py +30 -18
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/functions.py +5 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/session.py +21 -5
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/catalog.py +28 -13
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/session.py +1 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/catalog.py +64 -24
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/dataframe.py +9 -5
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/functions.py +3 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/session.py +1 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/catalog.py +180 -10
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/functions.py +1 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/session.py +43 -14
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe.egg-info/PKG-INFO +6 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe.egg-info/requires.txt +8 -8
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/bigquery/test_bigquery_catalog.py +2 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/bigquery/test_bigquery_dataframe.py +15 -15
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/bigquery/test_bigquery_session.py +1 -1
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/duck/test_duckdb_catalog.py +12 -11
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/duck/test_duckdb_dataframe.py +50 -14
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/duck/test_duckdb_session.py +1 -1
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/postgres/test_postgres_catalog.py +6 -4
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/postgres/test_postgres_dataframe.py +7 -7
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/postgres/test_postgres_session.py +2 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/redshift/test_redshift_catalog.py +4 -4
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/redshift/test_redshift_session.py +2 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/snowflake/test_snowflake_catalog.py +50 -50
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/snowflake/test_snowflake_dataframe.py +44 -44
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/snowflake/test_snowflake_session.py +2 -2
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/spark/test_spark_catalog.py +4 -4
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/test_engine_dataframe.py +8 -33
- sqlframe-2.0.0/tests/integration/engines/test_engine_session.py +41 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/test_int_functions.py +118 -46
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/test_int_dataframe.py +68 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/fixtures.py +5 -1
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/test_dataframe.py +9 -9
- sqlframe-2.0.0/tests/unit/standalone/test_dataframe_writer.py +107 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/test_functions.py +5 -5
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/test_session.py +1 -1
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/test_util.py +1 -0
- sqlframe-1.13.0/sqlframe/base/decorators.py +0 -53
- sqlframe-1.13.0/tests/integration/engines/test_engine_session.py +0 -47
- sqlframe-1.13.0/tests/unit/standalone/test_dataframe_writer.py +0 -107
- {sqlframe-1.13.0 → sqlframe-2.0.0}/.github/CODEOWNERS +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/.github/workflows/main.workflow.yaml +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/.github/workflows/publish.workflow.yaml +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/.gitignore +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/.pre-commit-config.yaml +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/.readthedocs.yaml +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/LICENSE +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/add_chatgpt_support.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/adding_ai_to_meal.jpeg +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/hype_train.gif +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/marvin_paranoid_robot.gif +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/nonsense_sql.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/openai_full_rewrite.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/openai_replacing_cte_names.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/sqlglot_optimized_code.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/add_chatgpt_support/sunny_shake_head_no.gif +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/but_wait_theres_more.gif +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/cake.gif +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/images/you_get_pyspark_api.gif +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/blogs/sqlframe_universal_dataframe_api.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/bigquery.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/duckdb.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/images/SF.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/images/favicon.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/images/favicon_old.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/images/sqlframe_diagram.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/images/sqlframe_logo.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/docs/postgres.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/images/SF.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/images/favicon.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/images/favicon_old.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/images/sqlframe_diagram.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/images/sqlframe_logo.png +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/index.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/requirements.txt +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/spark.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/standalone.md +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/docs/stylesheets/extra.css +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/mkdocs.yml +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/pytest.ini +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/renovate.json +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/setup.cfg +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/LICENSE +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/_typing.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/exceptions.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/mixins/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/mixins/readwriter_mixins.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/normalize.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/operations.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/transforms.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/base/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/dataframe.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/functions.pyi +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/readwriter.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/bigquery/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/functions.pyi +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/duckdb/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/dataframe.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/functions.pyi +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/readwriter.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/postgres/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/dataframe.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/functions.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/readwriter.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/redshift/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/functions.pyi +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/readwriter.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/snowflake/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/dataframe.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/functions.pyi +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/readwriter.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/spark/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/catalog.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/dataframe.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/functions.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/group.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/readwriter.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/session.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/standalone/window.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/testing/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe/testing/utils.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe.egg-info/SOURCES.txt +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe.egg-info/dependency_links.txt +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/sqlframe.egg-info/top_level.txt +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/common_fixtures.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/conftest.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/fixtures/employee.csv +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/fixtures/employee.json +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/fixtures/employee.parquet +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/fixtures/employee_extra_line.csv +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/bigquery/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/duck/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/duck/test_duckdb_reader.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/postgres/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/redshift/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/snowflake/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/spark/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/spark/test_spark_dataframe.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/test_engine_column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/test_engine_reader.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/test_engine_writer.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/engines/test_int_testing.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/fixtures.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/test_int_dataframe_stats.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/test_int_grouped_data.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/integration/test_int_session.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/__init__.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/test_column.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/test_session_case_sensitivity.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/test_types.py +0 -0
- {sqlframe-1.13.0 → sqlframe-2.0.0}/tests/unit/standalone/test_window.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: sqlframe
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Turning PySpark Into a Universal DataFrame API
|
|
5
5
|
Home-page: https://github.com/eakmanrq/sqlframe
|
|
6
6
|
Author: Ryan Eakman
|
|
@@ -78,6 +78,10 @@ SQLFrame generates consistently accurate yet complex SQL for engine execution.
|
|
|
78
78
|
However, when using df.sql(), it produces more human-readable SQL.
|
|
79
79
|
For details on how to configure this output and leverage OpenAI to enhance the SQL, see [Generated SQL Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#generated-sql).
|
|
80
80
|
|
|
81
|
+
SQLFrame by default uses the Spark dialect for input and output.
|
|
82
|
+
This can be changed to make SQLFrame feel more like a native DataFrame API for the engine you are using.
|
|
83
|
+
See [Input and Output Dialect Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#input-and-output-dialect).
|
|
84
|
+
|
|
81
85
|
## Example Usage
|
|
82
86
|
|
|
83
87
|
```python
|
|
@@ -112,7 +116,7 @@ df = (
|
|
|
112
116
|
)
|
|
113
117
|
```
|
|
114
118
|
```python
|
|
115
|
-
>>> df.sql()
|
|
119
|
+
>>> df.sql(optimize=True)
|
|
116
120
|
WITH `t94228` AS (
|
|
117
121
|
SELECT
|
|
118
122
|
`natality`.`year` AS `year`,
|
|
@@ -48,6 +48,10 @@ SQLFrame generates consistently accurate yet complex SQL for engine execution.
|
|
|
48
48
|
However, when using df.sql(), it produces more human-readable SQL.
|
|
49
49
|
For details on how to configure this output and leverage OpenAI to enhance the SQL, see [Generated SQL Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#generated-sql).
|
|
50
50
|
|
|
51
|
+
SQLFrame by default uses the Spark dialect for input and output.
|
|
52
|
+
This can be changed to make SQLFrame feel more like a native DataFrame API for the engine you are using.
|
|
53
|
+
See [Input and Output Dialect Configuration](https://sqlframe.readthedocs.io/en/stable/configuration/#input-and-output-dialect).
|
|
54
|
+
|
|
51
55
|
## Example Usage
|
|
52
56
|
|
|
53
57
|
```python
|
|
@@ -82,7 +86,7 @@ df = (
|
|
|
82
86
|
)
|
|
83
87
|
```
|
|
84
88
|
```python
|
|
85
|
-
>>> df.sql()
|
|
89
|
+
>>> df.sql(optimize=True)
|
|
86
90
|
WITH `t94228` AS (
|
|
87
91
|
SELECT
|
|
88
92
|
`natality`.`year` AS `year`,
|
|
@@ -446,6 +446,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
446
446
|
* [trim](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.trim.html)
|
|
447
447
|
* [trunc](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.trunc.html)
|
|
448
448
|
* Shorthand expressions not supported. Ex: Use `month` instead of `mon`
|
|
449
|
+
* [try_to_timestamp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.try_to_timestamp.html)
|
|
449
450
|
* [typeof](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.typeof.html)
|
|
450
451
|
* [ucase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.ucase.html)
|
|
451
452
|
* [unbase64](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.unbase64.html)
|
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# General Configuration
|
|
2
2
|
|
|
3
|
+
## Input and Output Dialect
|
|
4
|
+
|
|
5
|
+
By default, SQLFrame processes all string inputs using the Spark dialect (e.g., date format strings, SQL) and generates outputs in the Spark dialect (e.g., column names, data types).
|
|
6
|
+
This configuration is ideal if you aim to use the PySpark DataFrame API as if running on Spark while actually executing on another engine.
|
|
7
|
+
|
|
8
|
+
This configuration can be changed to make SQLFrame feel more like a native DataFrame API for the engine you are using.
|
|
9
|
+
|
|
10
|
+
Example: Using BigQuery to Change Default Behavior
|
|
11
|
+
|
|
12
|
+
```python
|
|
13
|
+
from sqlframe.bigquery import BigQuerySession
|
|
14
|
+
|
|
15
|
+
session = BigQuerySession.builder.config(
|
|
16
|
+
map={
|
|
17
|
+
"sqlframe.input.dialect": "bigquery",
|
|
18
|
+
"sqlframe.output.dialect": "bigquery",
|
|
19
|
+
}
|
|
20
|
+
).getOrCreate()
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
In this configuration, you can use BigQuery syntax for elements such as date format strings and will receive BigQuery column names and data types in the output.
|
|
24
|
+
|
|
25
|
+
SQLFrame supports multiple dialects, all of which can be specific as the `input_dialect` and `output_dialect`.
|
|
26
|
+
|
|
3
27
|
## Generated SQL
|
|
4
28
|
|
|
5
29
|
### Pretty
|
|
@@ -28,7 +52,9 @@ SELECT CAST(`a3`.`a` AS BIGINT) AS `a`, CAST(`a3`.`b` AS BIGINT) AS `b` FROM VAL
|
|
|
28
52
|
|
|
29
53
|
### Optimized
|
|
30
54
|
|
|
31
|
-
Optimized SQL is SQL that has been processed by SQLGlot's optimizer.
|
|
55
|
+
Optimized SQL is SQL that has been processed by SQLGlot's optimizer.
|
|
56
|
+
For complex queries this will significantly reduce the number of CTEs produced and remove extra unused columns.
|
|
57
|
+
Defaults to `False`.
|
|
32
58
|
|
|
33
59
|
```python
|
|
34
60
|
from sqlframe.bigquery import BigQuerySession
|
|
@@ -177,7 +203,9 @@ LIMIT 5
|
|
|
177
203
|
|
|
178
204
|
### Override Dialect
|
|
179
205
|
|
|
180
|
-
The dialect of the generated SQL will be based on the session's
|
|
206
|
+
The dialect of the generated SQL will be based on the session's output dialect.
|
|
207
|
+
However, you can override the dialect by passing a string to the `dialect` parameter.
|
|
208
|
+
This is useful when you want to generate SQL for a different database.
|
|
181
209
|
|
|
182
210
|
```python
|
|
183
211
|
# create session and `df` like normal
|
|
@@ -279,6 +279,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
279
279
|
* [date_format](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.date_format.html)
|
|
280
280
|
* [date_sub](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.date_sub.html)
|
|
281
281
|
* [date_trunc](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.date_trunc.html)
|
|
282
|
+
* [day](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.day.html)
|
|
282
283
|
* [dayofmonth](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.dayofmonth.html)
|
|
283
284
|
* [dayofweek](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.dayofweek.html)
|
|
284
285
|
* [dayofyear](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.dayofyear.html)
|
|
@@ -292,6 +293,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
292
293
|
* [element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.element_at.html)
|
|
293
294
|
* Only works on strings (does not work on arrays)
|
|
294
295
|
* [encode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.encode.html)
|
|
296
|
+
* [endswith](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.Column.endswith.html)
|
|
295
297
|
* [exp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.exp.html)
|
|
296
298
|
* [explode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.explode.html)
|
|
297
299
|
* [expm1](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.expm1.html)
|
|
@@ -319,6 +321,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
319
321
|
* [kurtosis](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.kurtosis.html)
|
|
320
322
|
* [lag](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lag.html)
|
|
321
323
|
* [last](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.last.html)
|
|
324
|
+
* [last_day](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.last_day.html)
|
|
322
325
|
* [lcase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lcase.html)
|
|
323
326
|
* [lead](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lead.html)
|
|
324
327
|
* [least](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.least.html)
|
|
@@ -411,6 +414,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
411
414
|
* [trim](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.trim.html)
|
|
412
415
|
* [trunc](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.trunc.html)
|
|
413
416
|
* [try_element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.try_element_at.html)
|
|
417
|
+
* [try_to_timestamp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.try_to_timestamp.html)
|
|
414
418
|
* [typeof](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.typeof.html)
|
|
415
419
|
* [ucase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.ucase.html)
|
|
416
420
|
* [unbase64](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.unbase64.html)
|
|
@@ -300,6 +300,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
300
300
|
* [element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.element_at.html)
|
|
301
301
|
* Only works on strings (does not work on arrays)
|
|
302
302
|
* [encode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.encode.html)
|
|
303
|
+
* [endswith](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.Column.endswith.html)
|
|
303
304
|
* [exp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.exp.html)
|
|
304
305
|
* [explode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.explode.html)
|
|
305
306
|
* Doesn't support exploding maps
|
|
@@ -320,6 +321,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
320
321
|
* [isnan](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.isnan.html)
|
|
321
322
|
* [isnull](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.isnull.html)
|
|
322
323
|
* [lag](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lag.html)
|
|
324
|
+
* [last_day](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.last_day.html)
|
|
323
325
|
* [lcase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lcase.html)
|
|
324
326
|
* [lead](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.lead.html)
|
|
325
327
|
* [least](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.least.html)
|
|
@@ -403,6 +405,8 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
403
405
|
* [trunc](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.trunc.html)
|
|
404
406
|
* [try_element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.try_element_at.html)
|
|
405
407
|
* Negative index returns null and cannot lookup elements in maps
|
|
408
|
+
* [try_to_timestamp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.try_to_timestamp.html)
|
|
409
|
+
* [typeof](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.typeof.html)
|
|
406
410
|
* [ucase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.ucase.html)
|
|
407
411
|
* [unbase64](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.unbase64.html)
|
|
408
412
|
* [unix_timestamp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.unix_timestamp.html)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Snowflake
|
|
2
2
|
|
|
3
3
|
## Installation
|
|
4
4
|
|
|
@@ -319,6 +319,7 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
319
319
|
* [desc_nulls_last](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.desc_nulls_last.html)
|
|
320
320
|
* [e](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.e.html)
|
|
321
321
|
* [element_at](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.element_at.html)
|
|
322
|
+
* [endswith](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.Column.endswith.html)
|
|
322
323
|
* [exp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.exp.html)
|
|
323
324
|
* [explode](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.explode.html)
|
|
324
325
|
* [expm1](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.expm1.html)
|
|
@@ -444,6 +445,8 @@ See something that you would like to see supported? [Open an issue](https://gith
|
|
|
444
445
|
* [translate](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.translate.html)
|
|
445
446
|
* [trim](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.trim.html)
|
|
446
447
|
* [trunc](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.trunc.html)
|
|
448
|
+
* [try_to_timestamp](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.try_to_timestamp.html)
|
|
449
|
+
* [typeof](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.typeof.html)
|
|
447
450
|
* [ucase](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.ucase.html)
|
|
448
451
|
* [unbase64](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.unbase64.html)
|
|
449
452
|
* [unhex](https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.unhex.html)
|
|
@@ -20,7 +20,7 @@ setup(
|
|
|
20
20
|
python_requires=">=3.8",
|
|
21
21
|
install_requires=[
|
|
22
22
|
"prettytable<3.11.0",
|
|
23
|
-
"sqlglot>=24.0.0,<25.
|
|
23
|
+
"sqlglot>=24.0.0,<25.9",
|
|
24
24
|
"typing_extensions>=4.8,<5",
|
|
25
25
|
],
|
|
26
26
|
extras_require={
|
|
@@ -30,18 +30,18 @@ setup(
|
|
|
30
30
|
],
|
|
31
31
|
"dev": [
|
|
32
32
|
"duckdb>=0.9,<1.1",
|
|
33
|
-
"mypy>=1.10.0,<1.
|
|
34
|
-
"openai>=1.30,<1.
|
|
33
|
+
"mypy>=1.10.0,<1.12",
|
|
34
|
+
"openai>=1.30,<1.38",
|
|
35
35
|
"pandas>=2,<3",
|
|
36
36
|
"pandas-stubs>=2,<3",
|
|
37
37
|
"psycopg>=3.1,<4",
|
|
38
|
-
"pyarrow>=10,<
|
|
38
|
+
"pyarrow>=10,<18",
|
|
39
39
|
"pyspark>=2,<3.6",
|
|
40
|
-
"pytest>=8.2.0,<8.
|
|
40
|
+
"pytest>=8.2.0,<8.4",
|
|
41
41
|
"pytest-postgresql>=6,<7",
|
|
42
42
|
"pytest-xdist>=3.6,<3.7",
|
|
43
43
|
"pre-commit>=3.5;python_version=='3.8'",
|
|
44
|
-
"pre-commit>=3.7,<3.
|
|
44
|
+
"pre-commit>=3.7,<3.9;python_version>='3.9'",
|
|
45
45
|
"ruff>=0.4.4,<0.6",
|
|
46
46
|
"types-psycopg2>=2.9,<3",
|
|
47
47
|
],
|
|
@@ -57,7 +57,7 @@ setup(
|
|
|
57
57
|
"pandas>=2,<3",
|
|
58
58
|
],
|
|
59
59
|
"openai": [
|
|
60
|
-
"openai>=1.30,<1.
|
|
60
|
+
"openai>=1.30,<1.38",
|
|
61
61
|
],
|
|
62
62
|
"pandas": [
|
|
63
63
|
"pandas>=2,<3",
|
|
@@ -69,7 +69,7 @@ setup(
|
|
|
69
69
|
"redshift_connector>=2.1.1,<2.2.0",
|
|
70
70
|
],
|
|
71
71
|
"snowflake": [
|
|
72
|
-
"snowflake-connector-python[secure-local-storage]>=3.10.0,<3.
|
|
72
|
+
"snowflake-connector-python[secure-local-storage]>=3.10.0,<3.13",
|
|
73
73
|
],
|
|
74
74
|
"spark": [
|
|
75
75
|
"pyspark>=2,<3.6",
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import typing as t
|
|
6
|
+
from collections import defaultdict
|
|
6
7
|
|
|
7
8
|
from sqlglot import MappingSchema, exp
|
|
8
9
|
|
|
9
|
-
from sqlframe.base.decorators import normalize
|
|
10
10
|
from sqlframe.base.exceptions import TableSchemaError
|
|
11
|
-
from sqlframe.base.util import ensure_column_mapping, to_schema
|
|
11
|
+
from sqlframe.base.util import ensure_column_mapping, normalize_string, to_schema
|
|
12
12
|
|
|
13
13
|
if t.TYPE_CHECKING:
|
|
14
14
|
from sqlglot.schema import ColumnMapping
|
|
@@ -33,6 +33,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
33
33
|
"""Create a new Catalog that wraps the underlying JVM object."""
|
|
34
34
|
self.session = sparkSession
|
|
35
35
|
self._schema = schema or MappingSchema()
|
|
36
|
+
self._quoted_columns: t.Dict[exp.Table, t.List[str]] = defaultdict(list)
|
|
36
37
|
|
|
37
38
|
@property
|
|
38
39
|
def spark(self) -> SESSION:
|
|
@@ -52,7 +53,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
52
53
|
def get_columns_from_schema(self, table: exp.Table | str) -> t.Dict[str, exp.DataType]:
|
|
53
54
|
table = self.ensure_table(table)
|
|
54
55
|
return {
|
|
55
|
-
exp.column(name, quoted=
|
|
56
|
+
exp.column(name, quoted=name in self._quoted_columns[table]).sql(
|
|
56
57
|
dialect=self.session.input_dialect
|
|
57
58
|
): exp.DataType.build(dtype, dialect=self.session.input_dialect)
|
|
58
59
|
for name, dtype in self._schema.find(table, raise_on_missing=True).items() # type: ignore
|
|
@@ -64,9 +65,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
64
65
|
if not columns:
|
|
65
66
|
return {}
|
|
66
67
|
return {
|
|
67
|
-
exp.
|
|
68
|
-
dialect=self.session.input_dialect
|
|
69
|
-
): exp.DataType.build(c.dataType, dialect=self.session.input_dialect)
|
|
68
|
+
c.name: exp.DataType.build(c.dataType, dialect=self.session.output_dialect)
|
|
70
69
|
for c in columns
|
|
71
70
|
}
|
|
72
71
|
|
|
@@ -79,16 +78,30 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
79
78
|
return
|
|
80
79
|
if not column_mapping:
|
|
81
80
|
try:
|
|
82
|
-
column_mapping =
|
|
81
|
+
column_mapping = {
|
|
82
|
+
normalize_string(
|
|
83
|
+
k, from_dialect="output", to_dialect="input", is_column=True
|
|
84
|
+
): normalize_string(
|
|
85
|
+
v.sql(dialect=self.session.output_dialect),
|
|
86
|
+
from_dialect="output",
|
|
87
|
+
to_dialect="input",
|
|
88
|
+
is_datatype=True,
|
|
89
|
+
)
|
|
90
|
+
for k, v in self.get_columns(table).items()
|
|
91
|
+
}
|
|
83
92
|
except NotImplementedError:
|
|
84
93
|
# TODO: Add doc link
|
|
85
94
|
raise TableSchemaError(
|
|
86
95
|
"This session does not have access to a catalog that can lookup column information. See docs for explicitly defining columns or using a session that can automatically determine this."
|
|
87
96
|
)
|
|
88
97
|
column_mapping = ensure_column_mapping(column_mapping) # type: ignore
|
|
98
|
+
for column_name in column_mapping:
|
|
99
|
+
column = exp.to_column(column_name, dialect=self.session.input_dialect)
|
|
100
|
+
if column.this.quoted:
|
|
101
|
+
self._quoted_columns[table].append(column.this.name)
|
|
102
|
+
|
|
89
103
|
self._schema.add_table(table, column_mapping, dialect=self.session.input_dialect)
|
|
90
104
|
|
|
91
|
-
@normalize(["dbName"])
|
|
92
105
|
def getDatabase(self, dbName: str) -> Database:
|
|
93
106
|
"""Get the database with the specified name.
|
|
94
107
|
This throws an :class:`AnalysisException` when the database cannot be found.
|
|
@@ -115,6 +128,7 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
115
128
|
>>> spark.catalog.getDatabase("spark_catalog.default")
|
|
116
129
|
Database(name='default', catalog='spark_catalog', description='default database', ...
|
|
117
130
|
"""
|
|
131
|
+
dbName = normalize_string(dbName, from_dialect="input", is_schema=True)
|
|
118
132
|
schema = to_schema(dbName, dialect=self.session.input_dialect)
|
|
119
133
|
database_name = schema.db
|
|
120
134
|
databases = self.listDatabases(pattern=database_name)
|
|
@@ -122,12 +136,16 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
122
136
|
raise ValueError(f"Database '{dbName}' not found")
|
|
123
137
|
if len(databases) > 1:
|
|
124
138
|
if schema.catalog is not None:
|
|
125
|
-
filtered_databases = [
|
|
139
|
+
filtered_databases = [
|
|
140
|
+
db
|
|
141
|
+
for db in databases
|
|
142
|
+
if normalize_string(db.catalog, from_dialect="output", to_dialect="input") # type: ignore
|
|
143
|
+
== schema.catalog
|
|
144
|
+
]
|
|
126
145
|
if filtered_databases:
|
|
127
146
|
return filtered_databases[0]
|
|
128
147
|
return databases[0]
|
|
129
148
|
|
|
130
|
-
@normalize(["dbName"])
|
|
131
149
|
def databaseExists(self, dbName: str) -> bool:
|
|
132
150
|
"""Check if the database with the specified name exists.
|
|
133
151
|
|
|
@@ -168,7 +186,6 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
168
186
|
except ValueError:
|
|
169
187
|
return False
|
|
170
188
|
|
|
171
|
-
@normalize(["tableName"])
|
|
172
189
|
def getTable(self, tableName: str) -> Table:
|
|
173
190
|
"""Get the table or view with the specified name. This table can be a temporary view or a
|
|
174
191
|
table/view. This throws an :class:`AnalysisException` when no Table can be found.
|
|
@@ -210,13 +227,18 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
210
227
|
...
|
|
211
228
|
AnalysisException: ...
|
|
212
229
|
"""
|
|
230
|
+
tableName = normalize_string(tableName, from_dialect="input", is_table=True)
|
|
213
231
|
table = exp.to_table(tableName, dialect=self.session.input_dialect)
|
|
214
232
|
schema = table.copy()
|
|
215
233
|
schema.set("this", None)
|
|
216
234
|
tables = self.listTables(
|
|
217
235
|
schema.sql(dialect=self.session.input_dialect) if schema.db else None
|
|
218
236
|
)
|
|
219
|
-
matching_tables = [
|
|
237
|
+
matching_tables = [
|
|
238
|
+
t
|
|
239
|
+
for t in tables
|
|
240
|
+
if normalize_string(t.name, from_dialect="output", to_dialect="input") == table.name
|
|
241
|
+
]
|
|
220
242
|
if not matching_tables:
|
|
221
243
|
raise ValueError(f"Table '{tableName}' not found")
|
|
222
244
|
return matching_tables[0]
|
|
@@ -315,7 +337,6 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
315
337
|
raise ValueError(f"Function '{functionName}' not found")
|
|
316
338
|
return matching_functions[0]
|
|
317
339
|
|
|
318
|
-
@normalize(["tableName", "dbName"])
|
|
319
340
|
def tableExists(self, tableName: str, dbName: t.Optional[str] = None) -> bool:
|
|
320
341
|
"""Check if the table or view with the specified name exists.
|
|
321
342
|
This can either be a temporary view or a table/view.
|
|
@@ -389,6 +410,8 @@ class _BaseCatalog(t.Generic[SESSION, DF]):
|
|
|
389
410
|
>>> spark.catalog.tableExists("view1")
|
|
390
411
|
False
|
|
391
412
|
"""
|
|
413
|
+
tableName = normalize_string(tableName, from_dialect="input", is_table=True)
|
|
414
|
+
dbName = normalize_string(dbName, from_dialect="input", is_schema=True) if dbName else None
|
|
392
415
|
table = exp.to_table(tableName, dialect=self.session.input_dialect)
|
|
393
416
|
schema_arg = to_schema(dbName, dialect=self.session.input_dialect) if dbName else None
|
|
394
417
|
if not table.db:
|
|
@@ -7,11 +7,11 @@ import math
|
|
|
7
7
|
import typing as t
|
|
8
8
|
|
|
9
9
|
import sqlglot
|
|
10
|
+
from sqlglot import Dialect
|
|
10
11
|
from sqlglot import expressions as exp
|
|
11
12
|
from sqlglot.helper import flatten, is_iterable
|
|
12
13
|
from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
|
|
13
14
|
|
|
14
|
-
from sqlframe.base.decorators import normalize
|
|
15
15
|
from sqlframe.base.exceptions import UnsupportedOperationError
|
|
16
16
|
from sqlframe.base.types import DataType
|
|
17
17
|
from sqlframe.base.util import get_func_from_session, quote_preserving_alias_or_name
|
|
@@ -211,9 +211,8 @@ class Column:
|
|
|
211
211
|
def binary_op(
|
|
212
212
|
self, klass: t.Callable, other: ColumnOrLiteral, paren: bool = False, **kwargs
|
|
213
213
|
) -> Column:
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
)
|
|
214
|
+
other = self._lit(other) if isinstance(other, str) else Column(other)
|
|
215
|
+
op = klass(this=self.column_expression, expression=other.column_expression, **kwargs)
|
|
217
216
|
if paren:
|
|
218
217
|
return Column(exp.Paren(this=op))
|
|
219
218
|
return Column(op)
|
|
@@ -221,9 +220,8 @@ class Column:
|
|
|
221
220
|
def inverse_binary_op(
|
|
222
221
|
self, klass: t.Callable, other: ColumnOrLiteral, paren: bool = False, **kwargs
|
|
223
222
|
) -> Column:
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
)
|
|
223
|
+
other = self._lit(other) if isinstance(other, str) else Column(other)
|
|
224
|
+
op = klass(this=other.column_expression, expression=self.column_expression, **kwargs)
|
|
227
225
|
if paren:
|
|
228
226
|
return Column(exp.Paren(this=op))
|
|
229
227
|
return Column(op)
|
|
@@ -340,13 +338,17 @@ class Column:
|
|
|
340
338
|
new_expression = exp.Not(this=exp.Is(this=self.column_expression, expression=exp.Null()))
|
|
341
339
|
return Column(new_expression)
|
|
342
340
|
|
|
343
|
-
def cast(
|
|
341
|
+
def cast(
|
|
342
|
+
self, dataType: t.Union[str, DataType], dialect: t.Optional[t.Union[str, Dialect]] = None
|
|
343
|
+
) -> Column:
|
|
344
344
|
from sqlframe.base.session import _BaseSession
|
|
345
345
|
|
|
346
346
|
if isinstance(dataType, DataType):
|
|
347
347
|
dataType = dataType.simpleString()
|
|
348
348
|
return Column(
|
|
349
|
-
exp.cast(
|
|
349
|
+
exp.cast(
|
|
350
|
+
self.column_expression, dataType, dialect=dialect or _BaseSession().input_dialect
|
|
351
|
+
)
|
|
350
352
|
)
|
|
351
353
|
|
|
352
354
|
def startswith(self, value: t.Union[str, Column]) -> Column:
|