google-pso-data-validator 8.3.0__tar.gz → 8.4.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.
- {google_pso_data_validator-8.3.0/google_pso_data_validator.egg-info → google_pso_data_validator-8.4.0}/PKG-INFO +5 -3
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/README.md +2 -1
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/__main__.py +1 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/cli_tools.py +26 -12
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/clients.py +42 -13
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/config_manager.py +2 -2
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/consts.py +5 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/exceptions.py +4 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/partition_builder.py +10 -1
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/query_builder/random_row_builder.py +2 -1
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0/google_pso_data_validator.egg-info}/PKG-INFO +5 -3
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/google_pso_data_validator.egg-info/SOURCES.txt +5 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/google_pso_data_validator.egg-info/requires.txt +2 -1
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/setup.py +3 -2
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_addon/operations.py +15 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_bigquery/__init__.py +20 -10
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mssql/registry.py +1 -1
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_oracle/datatypes.py +1 -1
- google_pso_data_validator-8.4.0/third_party/ibis/ibis_sybase/__init__.py +186 -0
- google_pso_data_validator-8.4.0/third_party/ibis/ibis_sybase/api.py +42 -0
- google_pso_data_validator-8.4.0/third_party/ibis/ibis_sybase/compiler.py +101 -0
- google_pso_data_validator-8.4.0/third_party/ibis/ibis_sybase/datatypes.py +96 -0
- google_pso_data_validator-8.4.0/third_party/ibis/ibis_sybase/registry.py +209 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/LICENSE +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/app.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/client_info.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/combiner.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/data_validation.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/find_tables.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/gcs_helper.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/jellyfish_distance.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/metadata.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/query_builder/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/query_builder/partition_row_builder.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/query_builder/query_builder.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/raw_query.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/result_handlers/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/result_handlers/base_backend.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/result_handlers/bigquery.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/result_handlers/factory.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/result_handlers/postgres.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/result_handlers/text.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/schema_validation.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/secret_manager.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/state_manager.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/util.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/validation_builder.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/google_pso_data_validator.egg-info/dependency_links.txt +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/google_pso_data_validator.egg-info/entry_points.txt +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/google_pso_data_validator.egg-info/top_level.txt +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/setup.cfg +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_addon/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_addon/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_bigquery/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_bigquery/registry.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/client.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/compiler.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/datatypes.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/registry.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/tests/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/tests/conftest.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_cloud_spanner/to_pandas.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_db2/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_db2/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_db2/compiler.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_db2/datatypes.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_db2/registry.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_impala/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_impala/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mssql/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mssql/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mssql/datatypes.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mysql/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mysql/base_sql_compiler/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mysql/base_sql_compiler/select_builder.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_mysql/compiler.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_oracle/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_oracle/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_oracle/compiler.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_oracle/registry.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_postgres/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_postgres/client.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_postgres/datatypes.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_postgres/registry.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_redshift/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_redshift/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_redshift/compiler.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_snowflake/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_snowflake/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_snowflake/datatypes.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_teradata/__init__.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_teradata/api.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_teradata/compiler.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_teradata/datatypes.py +0 -0
- {google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/third_party/ibis/ibis_teradata/registry.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: google-pso-data-validator
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.4.0
|
|
4
4
|
Summary: A package to enable easy data validation
|
|
5
5
|
Author: PSO DVT Engineering team
|
|
6
6
|
Author-email: data-validator-eng@google.com
|
|
@@ -28,7 +28,7 @@ Requires-Dist: jellyfish>=1.1.0
|
|
|
28
28
|
Requires-Dist: pandas
|
|
29
29
|
Requires-Dist: parsy>=2.1
|
|
30
30
|
Requires-Dist: psycopg2-binary>=2.9.9
|
|
31
|
-
Requires-Dist: pyarrow
|
|
31
|
+
Requires-Dist: pyarrow
|
|
32
32
|
Requires-Dist: pydata-google-auth>=1.8.2
|
|
33
33
|
Requires-Dist: PyMySQL>=1.1.1
|
|
34
34
|
Requires-Dist: PyYAML>=6.0.2
|
|
@@ -45,6 +45,7 @@ Requires-Dist: freezegun; extra == "develop"
|
|
|
45
45
|
Requires-Dist: pyfakefs; extra == "develop"
|
|
46
46
|
Requires-Dist: pytest; extra == "develop"
|
|
47
47
|
Requires-Dist: pytest-cov; extra == "develop"
|
|
48
|
+
Requires-Dist: pytest-rerunfailures; extra == "develop"
|
|
48
49
|
Requires-Dist: pytest-timeout; extra == "develop"
|
|
49
50
|
Dynamic: author
|
|
50
51
|
Dynamic: author-email
|
|
@@ -92,8 +93,9 @@ DVT supports the following connection types:
|
|
|
92
93
|
* [Postgres](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#postgres)
|
|
93
94
|
* [Redshift](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#redshift)
|
|
94
95
|
* [Spanner](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#google-spanner)
|
|
95
|
-
* [Teradata](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#teradata)
|
|
96
96
|
* [Snowflake](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#snowflake)
|
|
97
|
+
* [Sybase ASE](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#sybase)
|
|
98
|
+
* [Teradata](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#teradata)
|
|
97
99
|
|
|
98
100
|
The [Connections](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md) page provides details about how to create
|
|
99
101
|
and list connections for the validation tool.
|
|
@@ -33,8 +33,9 @@ DVT supports the following connection types:
|
|
|
33
33
|
* [Postgres](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#postgres)
|
|
34
34
|
* [Redshift](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#redshift)
|
|
35
35
|
* [Spanner](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#google-spanner)
|
|
36
|
-
* [Teradata](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#teradata)
|
|
37
36
|
* [Snowflake](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#snowflake)
|
|
37
|
+
* [Sybase ASE](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#sybase)
|
|
38
|
+
* [Teradata](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#teradata)
|
|
38
39
|
|
|
39
40
|
The [Connections](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md) page provides details about how to create
|
|
40
41
|
and list connections for the validation tool.
|
{google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/__main__.py
RENAMED
|
@@ -596,6 +596,7 @@ def partition_and_store_config_files(args: "Namespace") -> None:
|
|
|
596
596
|
setattr(args, "custom_query_type", "row")
|
|
597
597
|
config_managers = build_config_managers_from_args(args, consts.CUSTOM_QUERY)
|
|
598
598
|
partition_builder = PartitionBuilder(config_managers, args)
|
|
599
|
+
partition_builder.check_partition_configs()
|
|
599
600
|
partition_builder.partition_configs()
|
|
600
601
|
|
|
601
602
|
|
{google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/cli_tools.py
RENAMED
|
@@ -73,6 +73,10 @@ if TYPE_CHECKING:
|
|
|
73
73
|
CONNECTION_SOURCE_FIELDS = {
|
|
74
74
|
consts.SOURCE_TYPE_BIGQUERY: [
|
|
75
75
|
["project_id", "GCP Project to use for BigQuery"],
|
|
76
|
+
[
|
|
77
|
+
"client_project_id",
|
|
78
|
+
"(Optional) BigQuery job/billing project (can differ from data project)",
|
|
79
|
+
],
|
|
76
80
|
["google_service_account_key_path", "(Optional) GCP SA Key Path"],
|
|
77
81
|
[
|
|
78
82
|
"api_endpoint",
|
|
@@ -84,7 +88,7 @@ CONNECTION_SOURCE_FIELDS = {
|
|
|
84
88
|
],
|
|
85
89
|
],
|
|
86
90
|
consts.SOURCE_TYPE_TERADATA: [
|
|
87
|
-
["host", "
|
|
91
|
+
["host", "Teradata host"],
|
|
88
92
|
["port", "Teradata port to connect on"],
|
|
89
93
|
["user_name", "User used to connect"],
|
|
90
94
|
["password", "Password for supplied user"],
|
|
@@ -93,7 +97,7 @@ CONNECTION_SOURCE_FIELDS = {
|
|
|
93
97
|
["json_params", "(Optional) Additional teradatasql JSON string parameters"],
|
|
94
98
|
],
|
|
95
99
|
consts.SOURCE_TYPE_ORACLE: [
|
|
96
|
-
["host", "
|
|
100
|
+
["host", "Oracle host"],
|
|
97
101
|
["port", "Oracle port to connect on"],
|
|
98
102
|
["user", "User used to connect"],
|
|
99
103
|
["thick_mode", "Flag indicating thick_mode"],
|
|
@@ -103,7 +107,7 @@ CONNECTION_SOURCE_FIELDS = {
|
|
|
103
107
|
["connect_args", "(Optional) Additional connection argument mapping"],
|
|
104
108
|
],
|
|
105
109
|
consts.SOURCE_TYPE_MSSQL: [
|
|
106
|
-
["host", "
|
|
110
|
+
["host", "SQL Server host (default localhost)"],
|
|
107
111
|
["port", "SQL Server port to connect on (default 1433)"],
|
|
108
112
|
["user", "User used to connect"],
|
|
109
113
|
["password", "Password for supplied user"],
|
|
@@ -112,7 +116,7 @@ CONNECTION_SOURCE_FIELDS = {
|
|
|
112
116
|
["url", "SQL Server SQLAlchemy connection URL"],
|
|
113
117
|
],
|
|
114
118
|
consts.SOURCE_TYPE_MYSQL: [
|
|
115
|
-
["host", "
|
|
119
|
+
["host", "MySQL host (default localhost)"],
|
|
116
120
|
["port", "MySQL port to connect on (default 3306)"],
|
|
117
121
|
["user", "User used to connect"],
|
|
118
122
|
["password", "Password for supplied user"],
|
|
@@ -126,14 +130,14 @@ CONNECTION_SOURCE_FIELDS = {
|
|
|
126
130
|
["connect_args", "(Optional) Additional connection argument mapping"],
|
|
127
131
|
],
|
|
128
132
|
consts.SOURCE_TYPE_POSTGRES: [
|
|
129
|
-
["host", "
|
|
133
|
+
["host", "PostgreSQL host."],
|
|
130
134
|
["port", "PostgreSQL port to connect on (e.g. 5432)"],
|
|
131
135
|
["user", "Username to connect to"],
|
|
132
136
|
["password", "Password for authentication of user"],
|
|
133
137
|
["database", "Database in PostgreSQL to connect to (default postgres)"],
|
|
134
138
|
],
|
|
135
139
|
consts.SOURCE_TYPE_REDSHIFT: [
|
|
136
|
-
["host", "
|
|
140
|
+
["host", "Redshift host."],
|
|
137
141
|
["port", "Redshift port to connect on (e.g. 5439)"],
|
|
138
142
|
["user", "Username to connect to"],
|
|
139
143
|
["password", "Password for authentication of user"],
|
|
@@ -149,16 +153,26 @@ CONNECTION_SOURCE_FIELDS = {
|
|
|
149
153
|
'(Optional) GCP Spanner API endpoint (e.g. "https://spanner-mypsc.p.googleapis.com")',
|
|
150
154
|
],
|
|
151
155
|
],
|
|
156
|
+
consts.SOURCE_TYPE_SYBASE: [
|
|
157
|
+
["host", "Sybase host (default localhost)"],
|
|
158
|
+
["port", "Sybase port to connect on (default 5000)"],
|
|
159
|
+
["user", "User used to connect"],
|
|
160
|
+
["password", "Password for supplied user"],
|
|
161
|
+
["database", "Database to connect to (default master)"],
|
|
162
|
+
["odbc_driver", "ODBC driver name"],
|
|
163
|
+
["query", "Connection query parameters"],
|
|
164
|
+
["url", "Sybase SQLAlchemy connection URL"],
|
|
165
|
+
],
|
|
152
166
|
consts.SOURCE_TYPE_FILESYSTEM: [
|
|
153
167
|
["table_name", "Table name to use as reference for file data"],
|
|
154
168
|
["file_path", "The local, s3, or GCS file path to the data"],
|
|
155
169
|
["file_type", "The file type of the file. 'csv', 'orc', 'parquet' or 'json'"],
|
|
156
170
|
],
|
|
157
171
|
consts.SOURCE_TYPE_IMPALA: [
|
|
158
|
-
["host", "
|
|
159
|
-
["port", "
|
|
160
|
-
["database", "
|
|
161
|
-
["auth_mechanism", "
|
|
172
|
+
["host", "Impala host"],
|
|
173
|
+
["port", "Impala port (10000 if not provided)"],
|
|
174
|
+
["database", "Impala database (default if not provided)"],
|
|
175
|
+
["auth_mechanism", "Impala auth mechanism (PLAIN if not provided)"],
|
|
162
176
|
[
|
|
163
177
|
"kerberos_service_name",
|
|
164
178
|
"Desired Kerberos service name ('impala' if not provided)",
|
|
@@ -183,8 +197,8 @@ CONNECTION_SOURCE_FIELDS = {
|
|
|
183
197
|
["http_path", "URL path of HTTP proxy"],
|
|
184
198
|
],
|
|
185
199
|
consts.SOURCE_TYPE_DB2: [
|
|
186
|
-
["host", "
|
|
187
|
-
["port", "
|
|
200
|
+
["host", "DB2 host"],
|
|
201
|
+
["port", "DB2 port (50000 if not provided)"],
|
|
188
202
|
["user", "Username to connect to"],
|
|
189
203
|
["password", "Password for authentication of user"],
|
|
190
204
|
["database", "Database in DB2 to connect to"],
|
{google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/clients.py
RENAMED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
from contextlib import contextmanager
|
|
17
17
|
import copy
|
|
18
18
|
import logging
|
|
19
|
-
from typing import TYPE_CHECKING
|
|
19
|
+
from typing import TYPE_CHECKING, Optional
|
|
20
20
|
import warnings
|
|
21
21
|
|
|
22
22
|
import google.oauth2.service_account
|
|
@@ -56,6 +56,7 @@ IBIS_ALCHEMY_BACKENDS = [
|
|
|
56
56
|
"mssql",
|
|
57
57
|
"redshift",
|
|
58
58
|
"snowflake",
|
|
59
|
+
"sybase",
|
|
59
60
|
]
|
|
60
61
|
|
|
61
62
|
|
|
@@ -93,19 +94,32 @@ try:
|
|
|
93
94
|
except ImportError:
|
|
94
95
|
db2_connect = _raise_missing_client_error("pip install ibm_db_sa")
|
|
95
96
|
|
|
97
|
+
# Sybase requires sqlalchemy_sybase package.
|
|
98
|
+
try:
|
|
99
|
+
from third_party.ibis.ibis_sybase.api import sybase_connect
|
|
100
|
+
except ImportError:
|
|
101
|
+
sybase_connect = _raise_missing_client_error("pip install sqlalchemy_sybase")
|
|
102
|
+
|
|
96
103
|
|
|
97
104
|
def get_google_bigquery_client(
|
|
98
|
-
project_id: str,
|
|
105
|
+
project_id: str,
|
|
106
|
+
credentials=None,
|
|
107
|
+
api_endpoint: Optional[str] = None,
|
|
108
|
+
quota_project_id: Optional[str] = None,
|
|
99
109
|
):
|
|
100
110
|
info = client_info.get_http_client_info()
|
|
101
111
|
job_config = bigquery.QueryJobConfig(
|
|
102
112
|
connection_properties=[bigquery.ConnectionProperty("time_zone", "UTC")]
|
|
103
113
|
)
|
|
114
|
+
effective_project = quota_project_id or project_id
|
|
104
115
|
options = None
|
|
105
|
-
if api_endpoint:
|
|
106
|
-
options = client_options.ClientOptions(
|
|
116
|
+
if api_endpoint or quota_project_id:
|
|
117
|
+
options = client_options.ClientOptions(
|
|
118
|
+
api_endpoint=api_endpoint,
|
|
119
|
+
quota_project_id=quota_project_id if quota_project_id else None,
|
|
120
|
+
)
|
|
107
121
|
return bigquery.Client(
|
|
108
|
-
project=
|
|
122
|
+
project=effective_project,
|
|
109
123
|
client_info=info,
|
|
110
124
|
credentials=credentials,
|
|
111
125
|
default_query_job_config=job_config,
|
|
@@ -113,10 +127,17 @@ def get_google_bigquery_client(
|
|
|
113
127
|
)
|
|
114
128
|
|
|
115
129
|
|
|
116
|
-
def _get_google_bqstorage_client(
|
|
130
|
+
def _get_google_bqstorage_client(
|
|
131
|
+
credentials=None,
|
|
132
|
+
api_endpoint: Optional[str] = None,
|
|
133
|
+
quota_project_id: Optional[str] = None,
|
|
134
|
+
):
|
|
117
135
|
options = None
|
|
118
|
-
if api_endpoint:
|
|
119
|
-
options = client_options.ClientOptions(
|
|
136
|
+
if api_endpoint or quota_project_id:
|
|
137
|
+
options = client_options.ClientOptions(
|
|
138
|
+
api_endpoint=api_endpoint,
|
|
139
|
+
quota_project_id=quota_project_id if quota_project_id else None,
|
|
140
|
+
)
|
|
120
141
|
from google.cloud import bigquery_storage_v1 as bigquery_storage
|
|
121
142
|
|
|
122
143
|
return bigquery_storage.BigQueryReadClient(
|
|
@@ -129,20 +150,26 @@ def get_bigquery_client(
|
|
|
129
150
|
project_id: str,
|
|
130
151
|
dataset_id: str = "",
|
|
131
152
|
credentials=None,
|
|
132
|
-
api_endpoint: str = None,
|
|
133
|
-
storage_api_endpoint: str = None,
|
|
153
|
+
api_endpoint: Optional[str] = None,
|
|
154
|
+
storage_api_endpoint: Optional[str] = None,
|
|
155
|
+
client_project_id: Optional[str] = None,
|
|
134
156
|
):
|
|
135
157
|
google_client = get_google_bigquery_client(
|
|
136
|
-
project_id,
|
|
158
|
+
project_id,
|
|
159
|
+
credentials=credentials,
|
|
160
|
+
api_endpoint=api_endpoint,
|
|
161
|
+
quota_project_id=client_project_id,
|
|
137
162
|
)
|
|
138
163
|
bqstorage_client = None
|
|
139
164
|
if storage_api_endpoint:
|
|
140
165
|
bqstorage_client = _get_google_bqstorage_client(
|
|
141
|
-
credentials=credentials,
|
|
166
|
+
credentials=credentials,
|
|
167
|
+
api_endpoint=storage_api_endpoint,
|
|
168
|
+
quota_project_id=client_project_id,
|
|
142
169
|
)
|
|
143
170
|
|
|
144
171
|
return bigquery_connect(
|
|
145
|
-
project_id=project_id,
|
|
172
|
+
project_id=project_id or client_project_id,
|
|
146
173
|
dataset_id=dataset_id,
|
|
147
174
|
credentials=credentials,
|
|
148
175
|
bigquery_client=google_client,
|
|
@@ -202,6 +229,7 @@ def get_ibis_table(client, schema_name, table_name, database_name=None):
|
|
|
202
229
|
"db2",
|
|
203
230
|
"mssql",
|
|
204
231
|
"redshift",
|
|
232
|
+
"sybase",
|
|
205
233
|
]:
|
|
206
234
|
return client.table(table_name, database=database_name, schema=schema_name)
|
|
207
235
|
elif client.name == "pandas":
|
|
@@ -400,5 +428,6 @@ CLIENT_LOOKUP = {
|
|
|
400
428
|
consts.SOURCE_TYPE_MSSQL: mssql_connect,
|
|
401
429
|
consts.SOURCE_TYPE_SNOWFLAKE: snowflake_connect,
|
|
402
430
|
consts.SOURCE_TYPE_SPANNER: spanner_connect,
|
|
431
|
+
consts.SOURCE_TYPE_SYBASE: sybase_connect,
|
|
403
432
|
consts.SOURCE_TYPE_DB2: db2_connect,
|
|
404
433
|
}
|
|
@@ -71,7 +71,7 @@ class ConfigManager(object):
|
|
|
71
71
|
"""Return config object."""
|
|
72
72
|
return self._config
|
|
73
73
|
|
|
74
|
-
def get_source_connection(self):
|
|
74
|
+
def get_source_connection(self) -> dict:
|
|
75
75
|
"""Return source connection object."""
|
|
76
76
|
if not self._source_conn:
|
|
77
77
|
if self._config.get(consts.CONFIG_SOURCE_CONN):
|
|
@@ -82,7 +82,7 @@ class ConfigManager(object):
|
|
|
82
82
|
|
|
83
83
|
return self._source_conn
|
|
84
84
|
|
|
85
|
-
def get_target_connection(self):
|
|
85
|
+
def get_target_connection(self) -> dict:
|
|
86
86
|
"""Return target connection object."""
|
|
87
87
|
if not self._target_conn:
|
|
88
88
|
if self._config.get(consts.CONFIG_TARGET_CONN):
|
{google_pso_data_validator-8.3.0 → google_pso_data_validator-8.4.0}/data_validation/consts.py
RENAMED
|
@@ -139,6 +139,7 @@ SOURCE_TYPE_POSTGRES = "Postgres"
|
|
|
139
139
|
SOURCE_TYPE_REDSHIFT = "Redshift"
|
|
140
140
|
SOURCE_TYPE_SNOWFLAKE = "Snowflake"
|
|
141
141
|
SOURCE_TYPE_SPANNER = "Spanner"
|
|
142
|
+
SOURCE_TYPE_SYBASE = "Sybase"
|
|
142
143
|
SOURCE_TYPE_TERADATA = "Teradata"
|
|
143
144
|
|
|
144
145
|
# BigQuery Result Handler Configs
|
|
@@ -149,6 +150,7 @@ TABLE_ID = "table_id"
|
|
|
149
150
|
GOOGLE_SERVICE_ACCOUNT_KEY_PATH = "google_service_account_key_path"
|
|
150
151
|
API_ENDPOINT = "api_endpoint"
|
|
151
152
|
STORAGE_API_ENDPOINT = "storage_api_endpoint"
|
|
153
|
+
CLIENT_PROJECT_ID = "client_project_id"
|
|
152
154
|
|
|
153
155
|
# Result Handler Output Table Fields
|
|
154
156
|
VALIDATION_TYPE = "validation_type"
|
|
@@ -262,3 +264,6 @@ CALC_FIELD_LENGTH = "length"
|
|
|
262
264
|
CALC_FIELD_PADDED_CHAR_LENGTH = "padded_char_length"
|
|
263
265
|
CALC_FIELD_RSTRIP = "rstrip"
|
|
264
266
|
CALC_FIELD_UPPER = "upper"
|
|
267
|
+
|
|
268
|
+
# Backends that do not support window functions.
|
|
269
|
+
NO_WINDOW_FUNCTION_SUPPORT = [SOURCE_TYPE_SYBASE]
|
|
@@ -20,7 +20,7 @@ import re
|
|
|
20
20
|
import datetime
|
|
21
21
|
from typing import List, Dict, TYPE_CHECKING
|
|
22
22
|
|
|
23
|
-
from data_validation import cli_tools, consts, util
|
|
23
|
+
from data_validation import cli_tools, consts, exceptions, util
|
|
24
24
|
from data_validation.config_manager import ConfigManager
|
|
25
25
|
from data_validation.query_builder.partition_row_builder import PartitionRowBuilder
|
|
26
26
|
from data_validation.validation_builder import ValidationBuilder
|
|
@@ -105,6 +105,15 @@ class PartitionBuilder:
|
|
|
105
105
|
yaml_configs_list = self._add_partition_filters(partition_filters)
|
|
106
106
|
self._store_partitions(yaml_configs_list)
|
|
107
107
|
|
|
108
|
+
def check_partition_configs(self) -> None:
|
|
109
|
+
for config_manager in self.config_managers:
|
|
110
|
+
source_type = config_manager.get_source_connection()[consts.SOURCE_TYPE]
|
|
111
|
+
if source_type in consts.NO_WINDOW_FUNCTION_SUPPORT:
|
|
112
|
+
raise exceptions.PartitionBuilderException(
|
|
113
|
+
f"Source client {source_type} does not support window functions, "
|
|
114
|
+
"please use this connection as a target connection for generate-table-partitions."
|
|
115
|
+
)
|
|
116
|
+
|
|
108
117
|
@staticmethod
|
|
109
118
|
def _extract_where(table_expr: "IbisTable", client: "BaseBackend") -> str:
|
|
110
119
|
"""Given a ibis table expression with a filter (i.e. WHERE) clause, this function extracts the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: google-pso-data-validator
|
|
3
|
-
Version: 8.
|
|
3
|
+
Version: 8.4.0
|
|
4
4
|
Summary: A package to enable easy data validation
|
|
5
5
|
Author: PSO DVT Engineering team
|
|
6
6
|
Author-email: data-validator-eng@google.com
|
|
@@ -28,7 +28,7 @@ Requires-Dist: jellyfish>=1.1.0
|
|
|
28
28
|
Requires-Dist: pandas
|
|
29
29
|
Requires-Dist: parsy>=2.1
|
|
30
30
|
Requires-Dist: psycopg2-binary>=2.9.9
|
|
31
|
-
Requires-Dist: pyarrow
|
|
31
|
+
Requires-Dist: pyarrow
|
|
32
32
|
Requires-Dist: pydata-google-auth>=1.8.2
|
|
33
33
|
Requires-Dist: PyMySQL>=1.1.1
|
|
34
34
|
Requires-Dist: PyYAML>=6.0.2
|
|
@@ -45,6 +45,7 @@ Requires-Dist: freezegun; extra == "develop"
|
|
|
45
45
|
Requires-Dist: pyfakefs; extra == "develop"
|
|
46
46
|
Requires-Dist: pytest; extra == "develop"
|
|
47
47
|
Requires-Dist: pytest-cov; extra == "develop"
|
|
48
|
+
Requires-Dist: pytest-rerunfailures; extra == "develop"
|
|
48
49
|
Requires-Dist: pytest-timeout; extra == "develop"
|
|
49
50
|
Dynamic: author
|
|
50
51
|
Dynamic: author-email
|
|
@@ -92,8 +93,9 @@ DVT supports the following connection types:
|
|
|
92
93
|
* [Postgres](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#postgres)
|
|
93
94
|
* [Redshift](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#redshift)
|
|
94
95
|
* [Spanner](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#google-spanner)
|
|
95
|
-
* [Teradata](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#teradata)
|
|
96
96
|
* [Snowflake](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#snowflake)
|
|
97
|
+
* [Sybase ASE](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#sybase)
|
|
98
|
+
* [Teradata](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md#teradata)
|
|
97
99
|
|
|
98
100
|
The [Connections](https://github.com/GoogleCloudPlatform/professional-services-data-validator/blob/develop/docs/connections.md) page provides details about how to create
|
|
99
101
|
and list connections for the validation tool.
|
|
@@ -85,6 +85,11 @@ third_party/ibis/ibis_redshift/compiler.py
|
|
|
85
85
|
third_party/ibis/ibis_snowflake/__init__.py
|
|
86
86
|
third_party/ibis/ibis_snowflake/api.py
|
|
87
87
|
third_party/ibis/ibis_snowflake/datatypes.py
|
|
88
|
+
third_party/ibis/ibis_sybase/__init__.py
|
|
89
|
+
third_party/ibis/ibis_sybase/api.py
|
|
90
|
+
third_party/ibis/ibis_sybase/compiler.py
|
|
91
|
+
third_party/ibis/ibis_sybase/datatypes.py
|
|
92
|
+
third_party/ibis/ibis_sybase/registry.py
|
|
88
93
|
third_party/ibis/ibis_teradata/__init__.py
|
|
89
94
|
third_party/ibis/ibis_teradata/api.py
|
|
90
95
|
third_party/ibis/ibis_teradata/compiler.py
|
|
@@ -12,7 +12,7 @@ jellyfish>=1.1.0
|
|
|
12
12
|
pandas
|
|
13
13
|
parsy>=2.1
|
|
14
14
|
psycopg2-binary>=2.9.9
|
|
15
|
-
pyarrow
|
|
15
|
+
pyarrow
|
|
16
16
|
pydata-google-auth>=1.8.2
|
|
17
17
|
PyMySQL>=1.1.1
|
|
18
18
|
PyYAML>=6.0.2
|
|
@@ -29,6 +29,7 @@ freezegun
|
|
|
29
29
|
pyfakefs
|
|
30
30
|
pytest
|
|
31
31
|
pytest-cov
|
|
32
|
+
pytest-rerunfailures
|
|
32
33
|
pytest-timeout
|
|
33
34
|
|
|
34
35
|
[pyspark]
|
|
@@ -18,7 +18,7 @@ import setuptools
|
|
|
18
18
|
|
|
19
19
|
name = "google-pso-data-validator"
|
|
20
20
|
description = "A package to enable easy data validation"
|
|
21
|
-
version = "8.
|
|
21
|
+
version = "8.4.0"
|
|
22
22
|
release_status = "Development Status :: 4 - Beta"
|
|
23
23
|
|
|
24
24
|
with open("README.md", "r") as fh:
|
|
@@ -39,7 +39,7 @@ dependencies = [
|
|
|
39
39
|
"pandas",
|
|
40
40
|
"parsy>=2.1",
|
|
41
41
|
"psycopg2-binary>=2.9.9",
|
|
42
|
-
"pyarrow
|
|
42
|
+
"pyarrow",
|
|
43
43
|
"pydata-google-auth>=1.8.2",
|
|
44
44
|
"PyMySQL>=1.1.1",
|
|
45
45
|
"PyYAML>=6.0.2",
|
|
@@ -57,6 +57,7 @@ extras_require = {
|
|
|
57
57
|
"pyfakefs",
|
|
58
58
|
"pytest",
|
|
59
59
|
"pytest-cov",
|
|
60
|
+
"pytest-rerunfailures",
|
|
60
61
|
"pytest-timeout",
|
|
61
62
|
],
|
|
62
63
|
}
|
|
@@ -92,6 +92,12 @@ try:
|
|
|
92
92
|
except Exception:
|
|
93
93
|
SnowflakeExprTranslator = None
|
|
94
94
|
|
|
95
|
+
# Sybase requires sqlalchemy_sybase package.
|
|
96
|
+
try:
|
|
97
|
+
from third_party.ibis.ibis_sybase.compiler import SybaseExprTranslator
|
|
98
|
+
except Exception:
|
|
99
|
+
SybaseExprTranslator = None
|
|
100
|
+
|
|
95
101
|
|
|
96
102
|
# Cast of datetime64 NaT to int64 and then in seconds results in the value below.
|
|
97
103
|
# We need to use this value in the datetime.date simulation of the datetime64 behaviour.
|
|
@@ -591,3 +597,12 @@ if SnowflakeExprTranslator:
|
|
|
591
597
|
SnowflakeExprTranslator._registry[ops.RandomScalar] = sa_format_random
|
|
592
598
|
SnowflakeExprTranslator._registry[BinaryLength] = sa_format_binary_length
|
|
593
599
|
SnowflakeExprTranslator._registry[ops.RStrip] = _sa_whitespace_rstrip
|
|
600
|
+
|
|
601
|
+
if SybaseExprTranslator:
|
|
602
|
+
SybaseExprTranslator._registry[
|
|
603
|
+
BinaryLength
|
|
604
|
+
] = mssql_registry.sa_format_binary_length
|
|
605
|
+
SybaseExprTranslator._registry[RawSQL] = sa_format_raw_sql
|
|
606
|
+
SybaseExprTranslator._registry[
|
|
607
|
+
PaddedCharLength
|
|
608
|
+
] = mssql_registry.sa_format_string_length
|
|
@@ -22,12 +22,12 @@ from pydata_google_auth import cache
|
|
|
22
22
|
from ibis.backends.bigquery import (
|
|
23
23
|
Backend as BigQueryBackend,
|
|
24
24
|
_create_client_info,
|
|
25
|
-
parse_project_and_dataset,
|
|
26
25
|
CLIENT_ID,
|
|
27
26
|
CLIENT_SECRET,
|
|
28
27
|
EXTERNAL_DATA_SCOPES,
|
|
29
28
|
SCOPES,
|
|
30
29
|
)
|
|
30
|
+
from ibis.backends.bigquery.client import parse_project_and_dataset
|
|
31
31
|
|
|
32
32
|
if TYPE_CHECKING:
|
|
33
33
|
import google.cloud.bigquery_storage_v1
|
|
@@ -53,9 +53,12 @@ class Backend(BigQueryBackend):
|
|
|
53
53
|
bqstorage_client: "google.cloud.bigquery_storage_v1.BigQueryReadClient" = None,
|
|
54
54
|
):
|
|
55
55
|
"""Copy of Ibis v5 BigQuery do_connect() customized for DVT, see original method for docs."""
|
|
56
|
-
|
|
56
|
+
client_project_id = (
|
|
57
|
+
bigquery_client.project if bigquery_client is not None else None
|
|
58
|
+
)
|
|
59
|
+
default_project_id = None
|
|
57
60
|
|
|
58
|
-
if credentials is None:
|
|
61
|
+
if bigquery_client is None and credentials is None:
|
|
59
62
|
scopes = SCOPES
|
|
60
63
|
if auth_external_data:
|
|
61
64
|
scopes = EXTERNAL_DATA_SCOPES
|
|
@@ -83,14 +86,11 @@ class Backend(BigQueryBackend):
|
|
|
83
86
|
credentials_cache=credentials_cache,
|
|
84
87
|
use_local_webserver=auth_local_webserver,
|
|
85
88
|
)
|
|
89
|
+
project_id = project_id or default_project_id
|
|
86
90
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
self.data_project,
|
|
91
|
-
self.billing_project,
|
|
92
|
-
self.dataset,
|
|
93
|
-
) = parse_project_and_dataset(project_id, dataset_id)
|
|
91
|
+
self.billing_project = client_project_id or project_id
|
|
92
|
+
self.data_project = project_id or self.billing_project
|
|
93
|
+
self.dataset = None
|
|
94
94
|
|
|
95
95
|
if bigquery_client is None:
|
|
96
96
|
self.client = bq.Client(
|
|
@@ -133,6 +133,16 @@ class Backend(BigQueryBackend):
|
|
|
133
133
|
query_result._project = orig_project
|
|
134
134
|
return arrow_obj
|
|
135
135
|
|
|
136
|
+
def _parse_project_and_dataset(self, dataset) -> tuple[str, str]:
|
|
137
|
+
"""Copied from Ibis code and modified to use self.data_project."""
|
|
138
|
+
if not dataset and not self.dataset:
|
|
139
|
+
raise ValueError("Unable to determine BigQuery dataset.")
|
|
140
|
+
project, _, dataset = parse_project_and_dataset(
|
|
141
|
+
self.data_project,
|
|
142
|
+
dataset or f"{self.data_project}.{self.dataset}",
|
|
143
|
+
)
|
|
144
|
+
return project, dataset
|
|
145
|
+
|
|
136
146
|
def list_primary_key_columns(self, database: str, table: str) -> list:
|
|
137
147
|
"""Return a list of primary key column names."""
|
|
138
148
|
# TODO: Related to issue-1253, it's not clear if this is possible, we should revisit if it becomes a requirement.
|
|
@@ -51,7 +51,7 @@ def sa_table_column(t, op):
|
|
|
51
51
|
|
|
52
52
|
|
|
53
53
|
def strftime(translator, op):
|
|
54
|
-
"""Use
|
|
54
|
+
"""Use SQL Server CONVERT() in place of STRFTIME().
|
|
55
55
|
|
|
56
56
|
This is pretty restrictive due to the limited styles offered by SQL Server,
|
|
57
57
|
we've just covered off the generic formats used when casting date based columns
|
|
@@ -91,7 +91,7 @@ _type_mapping = {
|
|
|
91
91
|
# _handle_failed_column_type_inference().
|
|
92
92
|
# This method has a flaw that is doesn't prefix the table name with the schema
|
|
93
93
|
# which causes a table not found exception.
|
|
94
|
-
# I (nj@2024-02-15) felt the simplest change was to add LONG RAW to
|
|
94
|
+
# I (nj@2024-02-15) felt the simplest change was to add LONG RAW to SQLAlchemy
|
|
95
95
|
# as a RAW variant, as below.
|
|
96
96
|
if "LONG RAW" not in OracleDialect_oracledb.ischema_names:
|
|
97
97
|
OracleDialect_oracledb.ischema_names["LONG RAW"] = oracle.RAW
|