soda-synapse 4.0.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: soda-synapse
3
+ Version: 4.0.5
4
+ Requires-Dist: soda-core==4.0.5
5
+ Requires-Dist: soda-sqlserver==4.0.5
6
+ Dynamic: requires-dist
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env python
2
+
3
+ from setuptools import setup
4
+
5
+ package_name = "soda-synapse"
6
+ package_version = "4.0.5"
7
+ description = "Soda Synapse V4"
8
+
9
+ requires = [
10
+ f"soda-core=={package_version}",
11
+ f"soda-sqlserver=={package_version}",
12
+ ]
13
+
14
+ setup(
15
+ name=package_name,
16
+ version=package_version,
17
+ install_requires=requires,
18
+ package_dir={"": "src"},
19
+ entry_points={
20
+ "soda.plugins.data_source.synapse": [
21
+ "SynapseDataSourceImpl = soda_synapse.common.data_sources.synapse_data_source:SynapseDataSourceImpl",
22
+ ],
23
+ },
24
+ )
@@ -0,0 +1,91 @@
1
+ import logging
2
+ from typing import Optional
3
+
4
+ from soda_core.common.data_source_connection import DataSourceConnection
5
+ from soda_core.common.dataset_identifier import DatasetIdentifier
6
+ from soda_core.common.logging_constants import soda_logger
7
+ from soda_core.common.sql_ast import COLUMN, INSERT_INTO, VALUES, VALUES_ROW
8
+ from soda_core.common.sql_dialect import SqlDialect
9
+ from soda_sqlserver.common.data_sources.sqlserver_data_source import (
10
+ SqlServerDataSourceImpl,
11
+ SqlServerSqlDialect,
12
+ )
13
+ from soda_synapse.common.data_sources.synapse_data_source_connection import (
14
+ SynapseDataSource as SynapseDataSourceModel,
15
+ )
16
+ from soda_synapse.common.data_sources.synapse_data_source_connection import (
17
+ SynapseDataSourceConnection,
18
+ )
19
+
20
+ logger: logging.Logger = soda_logger
21
+
22
+
23
+ class SynapseDataSourceImpl(SqlServerDataSourceImpl, model_class=SynapseDataSourceModel):
24
+ def __init__(self, data_source_model: SynapseDataSourceModel):
25
+ super().__init__(data_source_model=data_source_model)
26
+
27
+ def _create_sql_dialect(self) -> SqlDialect:
28
+ return SynapseSqlDialect(data_source_impl=self)
29
+
30
+ def _create_data_source_connection(self) -> DataSourceConnection:
31
+ return SynapseDataSourceConnection(
32
+ name=self.data_source_model.name, connection_properties=self.data_source_model.connection_properties
33
+ )
34
+
35
+
36
+ class SynapseSqlDialect(SqlServerSqlDialect):
37
+ def sql_expr_timestamp_truncate_day(self, timestamp_literal: str) -> str:
38
+ return f"DATETIMEFROMPARTS((datepart(YEAR, {timestamp_literal})), (datepart(MONTH, {timestamp_literal})), (datepart(DAY, {timestamp_literal})), 0, 0, 0, 0)"
39
+
40
+ def _build_insert_into_values_sql(self, insert_into: INSERT_INTO) -> str:
41
+ values_sql: str = "\n" + "\nUNION ALL ".join(
42
+ [self._build_insert_into_values_row_sql(value) for value in insert_into.values]
43
+ )
44
+ return values_sql
45
+
46
+ def _build_insert_into_values_row_sql(self, values: VALUES_ROW) -> str:
47
+ values_sql: str = "SELECT " + ", ".join([self.literal(value) for value in values.values])
48
+ values_sql = self.encode_string_for_sql(values_sql)
49
+ return values_sql
50
+
51
+ def build_cte_values_sql(self, values: VALUES, alias_columns: list[COLUMN] | None) -> str:
52
+ return "\nUNION ALL\n".join(["SELECT " + self.build_expression_sql(value) for value in values.values])
53
+
54
+ def select_all_paginated_sql(
55
+ self,
56
+ dataset_identifier: DatasetIdentifier,
57
+ columns: list[str],
58
+ filter: Optional[str],
59
+ order_by: list[str],
60
+ limit: int,
61
+ offset: int,
62
+ ) -> str:
63
+ """TODO: Synapse uses completely different pagination syntax, AST does not have enough flexibility for this yet."""
64
+ where_clauses = []
65
+
66
+ if filter:
67
+ where_clauses.append(SqlExpressionStr(filter))
68
+
69
+ select_statements = self._build_select_sql_lines([SELECT(columns or [STAR()])])
70
+ select = ", ".join(select_statements)
71
+ order_by_statements = self._build_order_by_lines([ORDER_BY_ASC(c) for c in order_by])
72
+ order_by = ", ".join(order_by_statements)
73
+ where_statements = self._build_where_sql_lines([WHERE.optional(AND.optional(where_clauses))])
74
+ where = ", ".join(where_statements)
75
+
76
+ query = f"""WITH src AS (
77
+ {select}, ROW_NUMBER()
78
+ OVER (
79
+ {order_by}
80
+ ) AS rn
81
+ FROM {self.build_fully_qualified_sql_name(dataset_identifier)} AS t
82
+ {where}
83
+ )
84
+ SELECT *
85
+ FROM src
86
+ WHERE rn > {offset}
87
+ AND rn <= {offset + limit}
88
+ ORDER BY rn;
89
+ """
90
+
91
+ return query
@@ -0,0 +1,70 @@
1
+ from __future__ import annotations
2
+
3
+ import logging
4
+ from abc import ABC
5
+ from typing import Literal, Union
6
+
7
+ from pydantic import Field
8
+ from soda_core.common.logging_constants import soda_logger
9
+ from soda_core.model.data_source.data_source import DataSourceBase
10
+ from soda_sqlserver.common.data_sources.sqlserver_data_source_connection import (
11
+ SqlServerActiveDirectoryAuthentication,
12
+ SqlServerActiveDirectoryInteractiveAuthentication,
13
+ SqlServerActiveDirectoryPasswordAuthentication,
14
+ SqlServerActiveDirectoryServicePrincipalAuthentication,
15
+ SqlServerConnectionProperties,
16
+ SqlServerDataSourceConnection,
17
+ SqlServerPasswordAuth,
18
+ )
19
+
20
+ logger: logging.Logger = soda_logger
21
+
22
+
23
+ CONTEXT_AUTHENTICATION_DESCRIPTION = "Use context authentication"
24
+
25
+
26
+ # All of these classes are just copies of the SQLServerConnectionProperties classes, but with the Synapse type
27
+ class SynapseConnectionProperties(SqlServerConnectionProperties, ABC):
28
+ pass
29
+
30
+
31
+ class SynapsePasswordAuth(SqlServerPasswordAuth, SynapseConnectionProperties):
32
+ pass
33
+
34
+
35
+ class SynapseActiveDirectoryAuthentication(SqlServerActiveDirectoryAuthentication, SynapseConnectionProperties):
36
+ pass
37
+
38
+
39
+ class SynapseActiveDirectoryInteractiveAuthentication(
40
+ SqlServerActiveDirectoryInteractiveAuthentication, SynapseConnectionProperties
41
+ ):
42
+ pass
43
+
44
+
45
+ class SynapseActiveDirectoryPasswordAuthentication(
46
+ SqlServerActiveDirectoryPasswordAuthentication, SynapseConnectionProperties
47
+ ):
48
+ pass
49
+
50
+
51
+ class SynapseActiveDirectoryServicePrincipalAuthentication(
52
+ SqlServerActiveDirectoryServicePrincipalAuthentication, SynapseConnectionProperties
53
+ ):
54
+ pass
55
+
56
+
57
+ class SynapseDataSource(DataSourceBase, ABC):
58
+ type: Literal["synapse"] = Field("synapse")
59
+
60
+ connection_properties: Union[
61
+ SynapsePasswordAuth,
62
+ SynapseActiveDirectoryInteractiveAuthentication,
63
+ SynapseActiveDirectoryPasswordAuthentication,
64
+ SynapseActiveDirectoryServicePrincipalAuthentication,
65
+ ] = Field(..., alias="connection", description="Synapse connection configuration")
66
+
67
+
68
+ class SynapseDataSourceConnection(SqlServerDataSourceConnection):
69
+ def _get_autocommit_setting(self) -> bool:
70
+ return True # Synapse requires autocommit to be True.
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ from typing import Optional
5
+
6
+ from soda_sqlserver.test_helpers.sqlserver_data_source_test_helper import (
7
+ SqlServerDataSourceTestHelper,
8
+ )
9
+
10
+
11
+ class SynapseDataSourceTestHelper(SqlServerDataSourceTestHelper):
12
+ def _create_database_name(self) -> Optional[str]:
13
+ return os.getenv("SYNAPSE_DATABASE", "sodatestingsynapse")
14
+
15
+ def _create_data_source_yaml_str(self) -> str:
16
+ """
17
+ Called in _create_data_source_impl to initialized self.data_source_impl
18
+ self.database_name and self.schema_name are available if appropriate for the data source type
19
+ """
20
+ return f"""
21
+ type: synapse
22
+ name: {self.name}
23
+ connection:
24
+ host: '{os.getenv("SYNAPSE_HOST", "localhost")}'
25
+ port: '{os.getenv("SYNAPSE_PORT", "1433")}'
26
+ database: '{os.getenv("SYNAPSE_DATABASE", "sodatestingsynapse")}'
27
+ authentication: '{os.getenv("SYNAPSE_AUTHENTICATION_TYPE", "activedirectoryserviceprincipal")}'
28
+ client_id: '{os.getenv("SYNAPSE_CLIENT_ID")}'
29
+ client_secret: '{os.getenv("SYNAPSE_CLIENT_SECRET")}'
30
+ trust_server_certificate: true
31
+ driver: '{os.getenv("SYNAPSE_DRIVER", "ODBC Driver 18 for SQL Server")}'
32
+ """
@@ -0,0 +1,6 @@
1
+ Metadata-Version: 2.4
2
+ Name: soda-synapse
3
+ Version: 4.0.5
4
+ Requires-Dist: soda-core==4.0.5
5
+ Requires-Dist: soda-sqlserver==4.0.5
6
+ Dynamic: requires-dist
@@ -0,0 +1,10 @@
1
+ setup.py
2
+ src/soda_synapse.egg-info/PKG-INFO
3
+ src/soda_synapse.egg-info/SOURCES.txt
4
+ src/soda_synapse.egg-info/dependency_links.txt
5
+ src/soda_synapse.egg-info/entry_points.txt
6
+ src/soda_synapse.egg-info/requires.txt
7
+ src/soda_synapse.egg-info/top_level.txt
8
+ src/soda_synapse/common/data_sources/synapse_data_source.py
9
+ src/soda_synapse/common/data_sources/synapse_data_source_connection.py
10
+ src/soda_synapse/test_helpers/synapse_data_source_test_helper.py
@@ -0,0 +1,2 @@
1
+ [soda.plugins.data_source.synapse]
2
+ SynapseDataSourceImpl = soda_synapse.common.data_sources.synapse_data_source:SynapseDataSourceImpl
@@ -0,0 +1,2 @@
1
+ soda-core==4.0.5
2
+ soda-sqlserver==4.0.5
@@ -0,0 +1 @@
1
+ soda_synapse