diff --git a/sqlalchemy_kusto/dbapi.py b/sqlalchemy_kusto/dbapi.py index ad195fc..cca7dce 100644 --- a/sqlalchemy_kusto/dbapi.py +++ b/sqlalchemy_kusto/dbapi.py @@ -14,7 +14,7 @@ def check_closed(func): def decorator(self, *args, **kwargs): if self.closed: - raise Exception("{klass} already closed".format(klass=self.__class__.__name__)) + raise ValueError("{klass} already closed".format(klass=self.__class__.__name__)) return func(self, *args, **kwargs) return decorator @@ -25,7 +25,7 @@ def check_result(func): def decorator(self, *args, **kwargs): if self._results is None: # pylint: disable=protected-access - raise Exception("Called before `execute`") + raise ValueError("Called before `execute`") return func(self, *args, **kwargs) return decorator @@ -35,12 +35,12 @@ def connect( cluster: str, database: str, msi: bool = False, - user_msi: str = None, + user_msi: Optional[str] = None, workload_identity: bool = False, - azure_ad_client_id: str = None, - azure_ad_client_secret: str = None, - azure_ad_tenant_id: str = None, -): + azure_ad_client_id: Optional[str] = None, + azure_ad_client_secret: Optional[str] = None, + azure_ad_tenant_id: Optional[str] = None, +): # pylint: disable=too-many-positional-arguments """Return a connection to the database.""" return Connection( cluster, @@ -63,11 +63,11 @@ def __init__( database: str, msi: bool = False, workload_identity: bool = False, - user_msi: str = None, - azure_ad_client_id: str = None, - azure_ad_client_secret: str = None, - azure_ad_tenant_id: str = None, - ): + user_msi: Optional[str] = None, + azure_ad_client_id: Optional[str] = None, + azure_ad_client_secret: Optional[str] = None, + azure_ad_tenant_id: Optional[str] = None, + ): # pylint: disable=too-many-positional-arguments self.closed = False self.cursors: List[Cursor] = [] kcsb = None @@ -82,9 +82,7 @@ def __init__( ) elif workload_identity: # Workload Identity - kcsb = KustoConnectionStringBuilder.with_azure_token_credential( - cluster, WorkloadIdentityCredential() - ) + kcsb = KustoConnectionStringBuilder.with_azure_token_credential(cluster, WorkloadIdentityCredential()) elif msi: # Managed Service Identity (MSI) if user_msi is None or user_msi == "": @@ -98,7 +96,7 @@ def __init__( else: # neither SP or MSI kcsb = KustoConnectionStringBuilder.with_az_cli_authentication(cluster) - kcsb._set_connector_details("sqlalchemy-kusto", "0.1.0") # pylint: disable=protected-access + kcsb._set_connector_details("sqlalchemy-kusto", "1.1.0") # pylint: disable=protected-access self.kusto_client = KustoClient(kcsb) self.database = database self.properties = ClientRequestProperties() @@ -162,7 +160,7 @@ def __init__( self.current_item_index = 0 self.properties = properties if properties is not None else ClientRequestProperties() - @property # type: ignore + @property @check_result @check_closed def rowcount(self) -> int: @@ -221,7 +219,7 @@ def fetchone(self): @check_result @check_closed - def fetchmany(self, size: int = None): + def fetchmany(self, size: Optional[int] = None): """ Fetches the next set of rows of a query result, returning a sequence of sequences (e.g. a list of tuples). An empty sequence is returned when diff --git a/sqlalchemy_kusto/dialect_base.py b/sqlalchemy_kusto/dialect_base.py index 3fd1cd5..21eb22f 100644 --- a/sqlalchemy_kusto/dialect_base.py +++ b/sqlalchemy_kusto/dialect_base.py @@ -166,7 +166,7 @@ def get_indexes( def get_unique_constraints(self, connection: Connection, table_name: str, schema: Optional[str] = None, **kwargs): return [] - def _check_unicode_returns(self, connection: Connection, additional_tests: List[Any] = None) -> bool: + def _check_unicode_returns(self, connection: Connection, additional_tests: Optional[List[Any]] = None) -> bool: return True def _check_unicode_description(self, connection: Connection) -> bool: diff --git a/sqlalchemy_kusto/dialect_kql.py b/sqlalchemy_kusto/dialect_kql.py index 449c54d..a1cf3f5 100644 --- a/sqlalchemy_kusto/dialect_kql.py +++ b/sqlalchemy_kusto/dialect_kql.py @@ -58,7 +58,7 @@ def visit_select( lateral=False, from_linter=None, **kwargs, - ): + ): # pylint: disable=too-many-positional-arguments logger.debug("Incoming query: %s", select_stmt) if len(select_stmt.get_final_froms()) != 1: raise NotSupportedError('Only single "select from" query is supported in kql compiler') @@ -325,7 +325,7 @@ def _extract_column_name_and_alias(column: Column) -> Tuple[str, Optional[str]]: return str(column), None @staticmethod - def _build_column_projection(column_name: str, column_alias: str = None, is_extend: bool = False) -> str: + def _build_column_projection(column_name: str, column_alias: Optional[str] = None, is_extend: bool = False) -> str: """Generates column alias semantic for project statement""" if is_extend: return ( @@ -367,7 +367,9 @@ def _convert_schema_in_statement(query: str) -> str: return query.replace(original, f'database("{unquoted_schema}").["{unquoted_table}"]', 1) @staticmethod - def _sql_to_kql_aggregate(sql_agg: str, column_name: str = None, is_distinct: bool = False) -> Optional[str]: + def _sql_to_kql_aggregate( + sql_agg: str, column_name: Optional[str] = None, is_distinct: bool = False + ) -> Optional[str]: """ Converts SQL aggregate function to KQL equivalent. If a column name is provided, applies it to the aggregate. diff --git a/tests/unit/test_dialect_kql.py b/tests/unit/test_dialect_kql.py index 8c6fefa..d7f90f5 100644 --- a/tests/unit/test_dialect_kql.py +++ b/tests/unit/test_dialect_kql.py @@ -1,5 +1,3 @@ -import re - import pytest import sqlalchemy as sa from sqlalchemy import ( @@ -11,15 +9,13 @@ column, create_engine, distinct, - func, literal_column, select, text, ) -from sqlalchemy.sql import sqltypes from sqlalchemy.sql.selectable import TextAsFrom -from sqlalchemy_kusto.dialect_kql import AGGREGATE_PATTERN, KustoKqlCompiler +from sqlalchemy_kusto.dialect_kql import KustoKqlCompiler engine = create_engine("kustokql+https://localhost/testdb")