зеркало из https://github.com/Azure/pykusto.git
Rename some methods to python standards, added some missing type hints
This commit is contained in:
Родитель
418bf364a6
Коммит
aa5c8152ae
|
@ -2,9 +2,11 @@
|
|||
<dictionary name="pykusto">
|
||||
<words>
|
||||
<w>acos</w>
|
||||
<w>asctime</w>
|
||||
<w>asin</w>
|
||||
<w>atan</w>
|
||||
<w>avgif</w>
|
||||
<w>bagexpansion</w>
|
||||
<w>buildschema</w>
|
||||
<w>countif</w>
|
||||
<w>countof</w>
|
||||
|
@ -19,34 +21,54 @@
|
|||
<w>endofweek</w>
|
||||
<w>endofyear</w>
|
||||
<w>extractjson</w>
|
||||
<w>fullouter</w>
|
||||
<w>getmonth</w>
|
||||
<w>getschema</w>
|
||||
<w>getyear</w>
|
||||
<w>hourofday</w>
|
||||
<w>ifexists</w>
|
||||
<w>indexof</w>
|
||||
<w>innerunique</w>
|
||||
<w>isempty</w>
|
||||
<w>isfinite</w>
|
||||
<w>isinf</w>
|
||||
<w>isnotempty</w>
|
||||
<w>isnotnull</w>
|
||||
<w>isutf</w>
|
||||
<w>itemindex</w>
|
||||
<w>kusto</w>
|
||||
<w>leftanti</w>
|
||||
<w>leftantisemi</w>
|
||||
<w>leftouter</w>
|
||||
<w>leftsemi</w>
|
||||
<w>levelname</w>
|
||||
<w>loggamma</w>
|
||||
<w>maxif</w>
|
||||
<w>minif</w>
|
||||
<w>monthofyear</w>
|
||||
<w>ncode</w>
|
||||
<w>nexec</w>
|
||||
<w>percentrank</w>
|
||||
<w>pykusto</w>
|
||||
<w>rightanti</w>
|
||||
<w>rightantisemi</w>
|
||||
<w>rightouter</w>
|
||||
<w>rightsemi</w>
|
||||
<w>sqrt</w>
|
||||
<w>startofday</w>
|
||||
<w>startofmonth</w>
|
||||
<w>startofweek</w>
|
||||
<w>startofyear</w>
|
||||
<w>stdev</w>
|
||||
<w>stdevif</w>
|
||||
<w>stdevp</w>
|
||||
<w>strcat</w>
|
||||
<w>strcmp</w>
|
||||
<w>strlen</w>
|
||||
<w>strrep</w>
|
||||
<w>subexpr</w>
|
||||
<w>substr</w>
|
||||
<w>sumif</w>
|
||||
<w>tdigest</w>
|
||||
<w>timespan</w>
|
||||
<w>toarray</w>
|
||||
|
@ -64,7 +86,10 @@
|
|||
<w>toreal</w>
|
||||
<w>totimespan</w>
|
||||
<w>toupper</w>
|
||||
<w>treepath</w>
|
||||
<w>urlquery</w>
|
||||
<w>varianceif</w>
|
||||
<w>variancep</w>
|
||||
<w>weekofyear</w>
|
||||
<w>welch</w>
|
||||
</words>
|
||||
|
|
|
@ -13,8 +13,7 @@ from azure.kusto.data.response import KustoResponseDataSet
|
|||
|
||||
from pykusto.expressions import BaseColumn, AnyTypeColumn
|
||||
from pykusto.item_fetcher import ItemFetcher
|
||||
from pykusto.kql_converters import KQL
|
||||
from pykusto.type_utils import INTERNAL_NAME_TO_TYPE, typed_column, DOT_NAME_TO_TYPE
|
||||
from pykusto.type_utils import INTERNAL_NAME_TO_TYPE, typed_column, DOT_NAME_TO_TYPE, KQL
|
||||
|
||||
|
||||
class KustoResponse:
|
||||
|
|
|
@ -2,9 +2,8 @@ from datetime import datetime, timedelta
|
|||
from typing import Any, List, Tuple, Mapping, Optional, Type
|
||||
from typing import Union
|
||||
|
||||
from pykusto.kql_converters import KQL
|
||||
from pykusto.type_utils import plain_expression, aggregation_expression, PythonTypes, kql_converter, KustoType, \
|
||||
typed_column
|
||||
typed_column, KQL
|
||||
|
||||
ExpressionType = Union[PythonTypes, 'BaseExpression']
|
||||
StringType = Union[str, 'StringExpression']
|
||||
|
@ -55,7 +54,7 @@ class BaseExpression:
|
|||
def as_subexpression(self) -> KQL:
|
||||
return KQL('({})'.format(self.kql))
|
||||
|
||||
def gettype(self) -> 'StringExpression':
|
||||
def get_type(self) -> 'StringExpression':
|
||||
return StringExpression(KQL('gettype({})'.format(self.kql)))
|
||||
|
||||
def __hash__(self) -> 'StringExpression':
|
||||
|
@ -234,10 +233,10 @@ class NumberExpression(BaseExpression):
|
|||
def isfinite(self) -> BooleanExpression:
|
||||
return BooleanExpression(KQL('isfinite({})'.format(self.kql)))
|
||||
|
||||
def isinf(self) -> BooleanExpression:
|
||||
def is_inf(self) -> BooleanExpression:
|
||||
return BooleanExpression(KQL('isinf({})'.format(self.kql)))
|
||||
|
||||
def isnan(self) -> BooleanExpression:
|
||||
def is_nan(self) -> BooleanExpression:
|
||||
return BooleanExpression(KQL('isnan({})'.format(self.kql)))
|
||||
|
||||
def log(self) -> 'NumberExpression':
|
||||
|
@ -249,7 +248,7 @@ class NumberExpression(BaseExpression):
|
|||
def log2(self) -> 'NumberExpression':
|
||||
return NumberExpression(KQL('log2({})'.format(self.kql)))
|
||||
|
||||
def loggamma(self) -> 'NumberExpression':
|
||||
def log_gamma(self) -> 'NumberExpression':
|
||||
return NumberExpression(KQL('loggamma({})'.format(self.kql)))
|
||||
|
||||
def round(self, precision: NumberType = None) -> 'NumberExpression':
|
||||
|
@ -351,28 +350,28 @@ class DatetimeExpression(BaseExpression):
|
|||
def bin_auto(self) -> 'DatetimeExpression':
|
||||
return DatetimeExpression(KQL('bin_auto({})'.format(self.kql)))
|
||||
|
||||
def endofday(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def end_of_day(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
if offset is None:
|
||||
res = 'endofday({})'.format(self.kql)
|
||||
else:
|
||||
res = 'endofday({}, {})'.format(self.kql, _subexpr_to_kql(offset))
|
||||
return DatetimeExpression(KQL(res))
|
||||
|
||||
def endofmonth(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def end_of_month(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
if offset is None:
|
||||
res = 'endofmonth({})'.format(self.kql)
|
||||
else:
|
||||
res = 'endofmonth({}, {})'.format(self.kql, _subexpr_to_kql(offset))
|
||||
return DatetimeExpression(KQL(res))
|
||||
|
||||
def endofweek(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def end_of_week(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
if offset is None:
|
||||
res = 'endofweek({})'.format(self.kql)
|
||||
else:
|
||||
res = 'endofweek({}, {})'.format(self.kql, _subexpr_to_kql(offset))
|
||||
return DatetimeExpression(KQL(res))
|
||||
|
||||
def endofyear(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def end_of_year(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
if offset is None:
|
||||
res = 'endofyear({})'.format(self.kql)
|
||||
else:
|
||||
|
@ -382,31 +381,31 @@ class DatetimeExpression(BaseExpression):
|
|||
def format_datetime(self, format_string: StringType) -> StringExpression:
|
||||
return StringExpression(KQL('format_datetime({}, {})'.format(self.kql, _subexpr_to_kql(format_string))))
|
||||
|
||||
def getmonth(self) -> NumberExpression:
|
||||
def get_month(self) -> NumberExpression:
|
||||
return NumberExpression(KQL('getmonth({})'.format(self.kql)))
|
||||
|
||||
def getyear(self) -> NumberExpression:
|
||||
def get_year(self) -> NumberExpression:
|
||||
return NumberExpression(KQL('getyear({})'.format(self.kql)))
|
||||
|
||||
def hourofday(self) -> NumberExpression:
|
||||
def hour_of_day(self) -> NumberExpression:
|
||||
return NumberExpression(KQL('hourofday({})'.format(self.kql)))
|
||||
|
||||
def startofday(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def start_of_day(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
return DatetimeExpression(KQL(
|
||||
('startofday({})' if offset is None else 'startofday({}, {})').format(self.kql, to_kql(offset))
|
||||
))
|
||||
|
||||
def startofmonth(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def start_of_month(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
return DatetimeExpression(KQL(
|
||||
('startofmonth({})' if offset is None else 'startofmonth({}, {})').format(self.kql, to_kql(offset))
|
||||
))
|
||||
|
||||
def startofweek(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def start_of_week(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
return DatetimeExpression(KQL(
|
||||
('startofweek({})' if offset is None else 'startofweek({}, {})').format(self.kql, to_kql(offset))
|
||||
))
|
||||
|
||||
def startofyear(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
def start_of_year(self, offset: NumberType = None) -> 'DatetimeExpression':
|
||||
return DatetimeExpression(KQL(
|
||||
('startofyear({})' if offset is None else 'startofyear({}, {})').format(self.kql, to_kql(offset))
|
||||
))
|
||||
|
|
|
@ -6,9 +6,8 @@ from pykusto.expressions import AnyTypeColumn, NumberType, NumberExpression, Tim
|
|||
ExpressionType, AggregationExpression, StringType, StringExpression, BooleanExpression, \
|
||||
NumberAggregationExpression, MappingAggregationExpression, ArrayAggregationExpression, to_kql, DynamicExpression, \
|
||||
ArrayExpression, ColumnToType, BaseColumn, AnyExpression, AnyAggregationExpression, MappingExpression
|
||||
from pykusto.kql_converters import KQL
|
||||
from pykusto.logger import logger
|
||||
from pykusto.type_utils import plain_expression, get_base_types, KustoType
|
||||
from pykusto.type_utils import plain_expression, get_base_types, KustoType, KQL
|
||||
|
||||
|
||||
class Functions:
|
||||
|
@ -180,20 +179,20 @@ class Functions:
|
|||
# def degrees(self): return
|
||||
|
||||
@staticmethod
|
||||
def endofday(expr: DatetimeExpression, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.endofday(offset)
|
||||
def end_of_day(expr: DatetimeExpression, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.end_of_day(offset)
|
||||
|
||||
@staticmethod
|
||||
def endofmonth(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.endofmonth(offset)
|
||||
def end_of_month(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.end_of_month(offset)
|
||||
|
||||
@staticmethod
|
||||
def endofweek(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.endofweek(offset)
|
||||
def end_of_week(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.end_of_week(offset)
|
||||
|
||||
@staticmethod
|
||||
def endofyear(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.endofyear(offset)
|
||||
def end_of_year(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.end_of_year(offset)
|
||||
|
||||
# def estimate_data_size(self): return
|
||||
|
||||
|
@ -239,16 +238,16 @@ class Functions:
|
|||
# def gamma(self): return
|
||||
|
||||
@staticmethod
|
||||
def getmonth(expr: DatetimeType) -> NumberExpression:
|
||||
return expr.getmonth()
|
||||
def get_month(expr: DatetimeType) -> NumberExpression:
|
||||
return expr.get_month()
|
||||
|
||||
@staticmethod
|
||||
def gettype(expr: ExpressionType) -> StringExpression:
|
||||
return expr.gettype()
|
||||
def get_type(expr: ExpressionType) -> StringExpression:
|
||||
return expr.get_type()
|
||||
|
||||
@staticmethod
|
||||
def getyear(expr: DatetimeType) -> NumberExpression:
|
||||
return expr.getyear()
|
||||
def get_year(expr: DatetimeType) -> NumberExpression:
|
||||
return expr.get_year()
|
||||
|
||||
@staticmethod
|
||||
def hash(expr: ExpressionType) -> StringExpression:
|
||||
|
@ -259,8 +258,8 @@ class Functions:
|
|||
return expr.hash_sha256()
|
||||
|
||||
@staticmethod
|
||||
def hourofday(expr: DatetimeType) -> NumberExpression:
|
||||
return expr.hourofday()
|
||||
def hour_of_day(expr: DatetimeType) -> NumberExpression:
|
||||
return expr.hour_of_day()
|
||||
|
||||
@staticmethod
|
||||
def iff(predicate: BooleanType, if_true: ExpressionType, if_false: ExpressionType) -> BaseExpression:
|
||||
|
@ -300,35 +299,35 @@ class Functions:
|
|||
# def isascii(self): return
|
||||
|
||||
@staticmethod
|
||||
def isempty(expr: ExpressionType) -> BooleanExpression:
|
||||
def is_empty(expr: ExpressionType) -> BooleanExpression:
|
||||
return expr.is_empty()
|
||||
|
||||
@staticmethod
|
||||
def isfinite(expr: NumberType) -> BooleanExpression:
|
||||
def is_finite(expr: NumberType) -> BooleanExpression:
|
||||
return expr.isfinite()
|
||||
|
||||
@staticmethod
|
||||
def isinf(expr: NumberType) -> BooleanExpression:
|
||||
return expr.isinf()
|
||||
def is_inf(expr: NumberType) -> BooleanExpression:
|
||||
return expr.is_inf()
|
||||
|
||||
@staticmethod
|
||||
def isnan(expr: NumberExpression) -> BooleanExpression:
|
||||
return expr.isnan()
|
||||
def is_nan(expr: NumberExpression) -> BooleanExpression:
|
||||
return expr.is_nan()
|
||||
|
||||
@staticmethod
|
||||
def isnotempty(expr: ExpressionType) -> BooleanExpression:
|
||||
def is_not_empty(expr: ExpressionType) -> BooleanExpression:
|
||||
return expr.is_not_empty()
|
||||
|
||||
@staticmethod
|
||||
def isnotnull(expr: ExpressionType) -> BooleanExpression:
|
||||
def is_not_null(expr: ExpressionType) -> BooleanExpression:
|
||||
return expr.is_not_null()
|
||||
|
||||
@staticmethod
|
||||
def isnull(expr: ExpressionType) -> BooleanExpression:
|
||||
def is_null(expr: ExpressionType) -> BooleanExpression:
|
||||
return expr.is_null()
|
||||
|
||||
@staticmethod
|
||||
def isutf8(expr: StringType) -> BooleanExpression:
|
||||
def is_utf8(expr: StringType) -> BooleanExpression:
|
||||
return expr.is_utf8()
|
||||
|
||||
@staticmethod
|
||||
|
@ -344,8 +343,8 @@ class Functions:
|
|||
return expr.log2()
|
||||
|
||||
@staticmethod
|
||||
def loggamma(expr: NumberType) -> NumberExpression:
|
||||
return expr.loggamma()
|
||||
def log_gamma(expr: NumberType) -> NumberExpression:
|
||||
return expr.log_gamma()
|
||||
|
||||
@staticmethod
|
||||
def make_datetime(year: NumberType,
|
||||
|
@ -376,7 +375,7 @@ class Functions:
|
|||
# def min_of(self): return
|
||||
|
||||
@staticmethod
|
||||
def monthofyear() -> NumberExpression: raise NotImplemented # TODO
|
||||
def month_of_year() -> NumberExpression: raise NotImplemented # TODO
|
||||
|
||||
@staticmethod
|
||||
def new_guid() -> AnyExpression: raise NotImplemented # TODO
|
||||
|
@ -576,20 +575,20 @@ class Functions:
|
|||
return NumberExpression(KQL('sqrt({})'.format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def startofday(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.startofday(offset)
|
||||
def start_of_day(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.start_of_day(offset)
|
||||
|
||||
@staticmethod
|
||||
def startofmonth(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.startofmonth(offset)
|
||||
def start_of_month(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.start_of_month(offset)
|
||||
|
||||
@staticmethod
|
||||
def startofweek(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.startofweek(offset)
|
||||
def start_of_week(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.start_of_week(offset)
|
||||
|
||||
@staticmethod
|
||||
def startofyear(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.startofyear(offset)
|
||||
def start_of_year(expr: DatetimeType, offset: NumberType = None) -> DatetimeExpression:
|
||||
return expr.start_of_year(offset)
|
||||
|
||||
@staticmethod
|
||||
def strcat(*strings: StringType) -> StringExpression:
|
||||
|
@ -654,60 +653,60 @@ class Functions:
|
|||
# def tdigest_merge(self): return
|
||||
|
||||
@staticmethod
|
||||
def tobool(expr: ExpressionType) -> BooleanExpression:
|
||||
def to_bool(expr: ExpressionType) -> BooleanExpression:
|
||||
return BooleanExpression(KQL('tobool({})'.format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def toboolean(expr: ExpressionType) -> BooleanExpression:
|
||||
def to_boolean(expr: ExpressionType) -> BooleanExpression:
|
||||
return BooleanExpression(KQL('toboolean({})'.format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def todatetime(expr: StringType) -> DatetimeExpression:
|
||||
def to_datetime(expr: StringType) -> DatetimeExpression:
|
||||
return DatetimeExpression(KQL('todatetime({})'.format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def todecimal(expr: NumberType) -> NumberExpression:
|
||||
def to_decimal(expr: NumberType) -> NumberExpression:
|
||||
return NumberExpression(KQL("todecimal({})".format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def todouble(expr: NumberType) -> NumberExpression:
|
||||
def to_double(expr: NumberType) -> NumberExpression:
|
||||
return NumberExpression(KQL("todouble({})".format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def todynamic() -> DynamicExpression: raise NotImplemented # TODO
|
||||
def to_dynamic() -> DynamicExpression: raise NotImplemented # TODO
|
||||
|
||||
@staticmethod
|
||||
def toguid() -> AnyExpression: raise NotImplemented # TODO
|
||||
def to_guid() -> AnyExpression: raise NotImplemented # TODO
|
||||
|
||||
@staticmethod
|
||||
def tohex(expr1: NumberType, expr2: NumberType = None) -> StringExpression:
|
||||
def to_hex(expr1: NumberType, expr2: NumberType = None) -> StringExpression:
|
||||
return StringExpression(KQL(('tohex({})' if expr2 is None else 'tohex({}, {})').format(to_kql(expr1), to_kql(expr2))))
|
||||
|
||||
@staticmethod
|
||||
def toint(expr: NumberType) -> NumberExpression:
|
||||
def to_int(expr: NumberType) -> NumberExpression:
|
||||
return NumberExpression(KQL("toint({})".format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def tolong(expr: NumberType) -> NumberExpression:
|
||||
def to_long(expr: NumberType) -> NumberExpression:
|
||||
return NumberExpression(KQL("tolong({})".format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def tolower(expr: StringType) -> StringExpression:
|
||||
def to_lower(expr: StringType) -> StringExpression:
|
||||
return expr.lower()
|
||||
|
||||
@staticmethod
|
||||
def toreal(expr: NumberType) -> NumberExpression:
|
||||
def to_real(expr: NumberType) -> NumberExpression:
|
||||
return NumberExpression(KQL("toreal({})".format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def tostring(expr: ExpressionType):
|
||||
def to_string(expr: ExpressionType):
|
||||
return expr.to_string()
|
||||
|
||||
@staticmethod
|
||||
def totimespan() -> TimespanExpression: raise NotImplemented # TODO
|
||||
def to_timespan() -> TimespanExpression: raise NotImplemented # TODO
|
||||
|
||||
@staticmethod
|
||||
def toupper(expr: StringType) -> StringExpression:
|
||||
def to_upper(expr: StringType) -> StringExpression:
|
||||
return expr.upper()
|
||||
|
||||
# def to_utf8(self): return
|
||||
|
@ -733,7 +732,7 @@ class Functions:
|
|||
def url_encode() -> StringExpression: raise NotImplemented # TODO
|
||||
|
||||
@staticmethod
|
||||
def weekofyear() -> NumberExpression: raise NotImplemented # TODO
|
||||
def week_of_year() -> NumberExpression: raise NotImplemented # TODO
|
||||
|
||||
# def welch_test(self): return
|
||||
|
||||
|
@ -764,7 +763,7 @@ class Functions:
|
|||
return NumberAggregationExpression(KQL('avg({})'.format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def avgif(expr: ExpressionType, predicate: BooleanType) -> NumberAggregationExpression:
|
||||
def avg_if(expr: ExpressionType, predicate: BooleanType) -> NumberAggregationExpression:
|
||||
return NumberAggregationExpression(KQL('avgif({}, {})'.format(to_kql(expr), to_kql(predicate))))
|
||||
|
||||
# def buildschema(self):
|
||||
|
@ -776,7 +775,7 @@ class Functions:
|
|||
return NumberAggregationExpression(KQL(res))
|
||||
|
||||
@staticmethod
|
||||
def countif(predicate: BooleanType) -> NumberAggregationExpression:
|
||||
def count_if(predicate: BooleanType) -> NumberAggregationExpression:
|
||||
return NumberAggregationExpression(KQL('countif({})'.format(to_kql(predicate))))
|
||||
|
||||
@staticmethod
|
||||
|
@ -786,7 +785,7 @@ class Functions:
|
|||
))
|
||||
|
||||
@staticmethod
|
||||
def dcountif(expr: ExpressionType, predicate: BooleanType, accuracy: NumberType = 0) -> NumberAggregationExpression:
|
||||
def dcount_if(expr: ExpressionType, predicate: BooleanType, accuracy: NumberType = 0) -> NumberAggregationExpression:
|
||||
return NumberAggregationExpression(KQL('dcountif({}, {}, {})'.format(
|
||||
to_kql(expr), to_kql(predicate), to_kql(accuracy)
|
||||
)))
|
||||
|
@ -860,7 +859,7 @@ class Functions:
|
|||
return AnyAggregationExpression(KQL('sum({})'.format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def sumif(expr: ExpressionType, predicate: BooleanType) -> AggregationExpression:
|
||||
def sum_if(expr: ExpressionType, predicate: BooleanType) -> AggregationExpression:
|
||||
return AnyAggregationExpression(KQL('sumif({}, {})'.format(to_kql(expr), to_kql(predicate))))
|
||||
|
||||
# def tdigest(self):
|
||||
|
@ -875,7 +874,7 @@ class Functions:
|
|||
return AnyAggregationExpression(KQL('variance({})'.format(to_kql(expr))))
|
||||
|
||||
@staticmethod
|
||||
def varianceif(expr: ExpressionType, predicate: BooleanType) -> AggregationExpression:
|
||||
def variance_if(expr: ExpressionType, predicate: BooleanType) -> AggregationExpression:
|
||||
return AnyAggregationExpression(KQL('varianceif({}, {})'.format(to_kql(expr), to_kql(predicate))))
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -84,7 +84,7 @@ class ItemFetcher(metaclass=ABCMeta):
|
|||
self.__items[name] = item
|
||||
return item
|
||||
|
||||
def _get_item(self, name: str, fallback: Callable) -> Any:
|
||||
def _get_item(self, name: str, fallback: Callable[[], Any]) -> Any:
|
||||
if self.__items is not None:
|
||||
resolved_item = self.__items.get(name)
|
||||
if resolved_item is not None:
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from itertools import chain
|
||||
from numbers import Number
|
||||
from typing import NewType, Mapping, Union, List, Tuple
|
||||
|
||||
from pykusto.type_utils import kql_converter, KustoType
|
||||
|
||||
KQL = NewType('KQL', str)
|
||||
|
||||
|
||||
@kql_converter(KustoType.DATETIME)
|
||||
def datetime_to_kql(dt: datetime) -> KQL:
|
||||
return KQL(dt.strftime('datetime(%Y-%m-%d %H:%M:%S.%f)'))
|
||||
|
||||
|
||||
@kql_converter(KustoType.TIMESPAN)
|
||||
def timedelta_to_kql(td: timedelta) -> KQL:
|
||||
hours, remainder = divmod(td.seconds, 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
return KQL('time({days}.{hours}:{minutes}:{seconds}.{microseconds})'.format(
|
||||
days=td.days,
|
||||
hours=hours,
|
||||
minutes=minutes,
|
||||
seconds=seconds,
|
||||
microseconds=td.microseconds,
|
||||
))
|
||||
|
||||
|
||||
@kql_converter(KustoType.ARRAY, KustoType.MAPPING)
|
||||
def dynamic_to_kql(d: Union[Mapping, List, Tuple]) -> KQL:
|
||||
try:
|
||||
query = list(json.dumps(d))
|
||||
except TypeError:
|
||||
# Using exceptions as part of normal flow is not best practice, however in this case we have a good reason.
|
||||
# The given object might contain a non-primitive object somewhere inside it, and the only way to find it is to go through the entire hierarchy, which is exactly
|
||||
# what's being done in the process of json conversion.
|
||||
# Also keep in mind that exception handling in Python has no performance overhead (unlike e.g. Java).
|
||||
return build_dynamic(d)
|
||||
|
||||
# Convert square brackets to round brackets (Issue #11)
|
||||
counter = 0
|
||||
prev = ""
|
||||
for i, c in enumerate(query):
|
||||
if counter == 0:
|
||||
if c == "[":
|
||||
query[i] = "("
|
||||
elif c == "]":
|
||||
query[i] = ")"
|
||||
elif c in ['"', '\''] and prev != "\\":
|
||||
counter += 1
|
||||
elif counter > 0:
|
||||
if c in ['"', '\''] and prev != "\\":
|
||||
counter -= 1
|
||||
prev = query[i]
|
||||
assert counter == 0
|
||||
return KQL("".join(query))
|
||||
|
||||
|
||||
def build_dynamic(d: Union[Mapping, List, Tuple]) -> KQL:
|
||||
from pykusto.expressions import BaseExpression
|
||||
if isinstance(d, BaseExpression):
|
||||
return d.kql
|
||||
if isinstance(d, Mapping):
|
||||
return KQL('pack({})'.format(', '.join(map(build_dynamic, chain(*d.items())))))
|
||||
if isinstance(d, (List, Tuple)):
|
||||
return KQL('pack_array({})'.format(', '.join(map(build_dynamic, d))))
|
||||
from pykusto.expressions import to_kql
|
||||
return to_kql(d)
|
||||
|
||||
|
||||
@kql_converter(KustoType.BOOL)
|
||||
def bool_to_kql(b: bool) -> KQL:
|
||||
return KQL('true') if b else KQL('false')
|
||||
|
||||
|
||||
@kql_converter(KustoType.STRING)
|
||||
def str_to_kql(s: str) -> KQL:
|
||||
return KQL('"{}"'.format(s))
|
||||
|
||||
|
||||
@kql_converter(KustoType.INT, KustoType.LONG, KustoType.REAL)
|
||||
def number_to_kql(n: Number) -> KQL:
|
||||
return KQL(str(n))
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
@kql_converter(KustoType.NULL)
|
||||
def none_to_kql(n: type(None)) -> KQL:
|
||||
return KQL("")
|
|
@ -10,9 +10,8 @@ from pykusto.expressions import BooleanType, ExpressionType, AggregationExpressi
|
|||
StringType, AssignmentBase, AssignmentFromAggregationToColumn, AssignmentToSingleColumn, AnyTypeColumn, \
|
||||
BaseExpression, \
|
||||
AssignmentFromColumnToColumn, AnyExpression, to_kql, ColumnToType
|
||||
from pykusto.kql_converters import KQL
|
||||
from pykusto.logger import logger
|
||||
from pykusto.type_utils import KustoType
|
||||
from pykusto.type_utils import KustoType, KQL
|
||||
from pykusto.udf import stringify_python_func
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import json
|
||||
from datetime import datetime, timedelta
|
||||
from enum import Enum
|
||||
from typing import Union, Mapping, Type, Dict, Callable, Tuple, List, Any, Set
|
||||
from itertools import chain
|
||||
from numbers import Number
|
||||
from typing import Union, Mapping, Type, Dict, Callable, Tuple, List, Any, Set, NewType
|
||||
|
||||
# TODO: Unhandled data types: guid, decimal
|
||||
PythonTypes = Union[str, int, float, bool, datetime, Mapping, List, Tuple, timedelta]
|
||||
KQL = NewType('KQL', str)
|
||||
|
||||
|
||||
class KustoType(Enum):
|
||||
|
@ -76,7 +80,7 @@ class TypeRegistrar:
|
|||
can then be used to retrieve the python type or function corresponding to a given Kusto type.
|
||||
"""
|
||||
name: str
|
||||
registry: Dict[KustoType, Callable]
|
||||
registry: Dict[KustoType, Callable[[Any], KQL]]
|
||||
|
||||
def __init__(self, name: str) -> None:
|
||||
"""
|
||||
|
@ -88,8 +92,8 @@ class TypeRegistrar:
|
|||
def __repr__(self) -> str:
|
||||
return self.name
|
||||
|
||||
def __call__(self, *types: KustoType) -> Callable:
|
||||
def inner(wrapped) -> Callable:
|
||||
def __call__(self, *types: KustoType) -> Callable[[Callable[[Any], KQL]], Callable[[Any], KQL]]:
|
||||
def inner(wrapped: Callable[[Any], KQL]) -> Callable[[Any], KQL]:
|
||||
for t in types:
|
||||
previous = self.registry.setdefault(t, wrapped)
|
||||
if previous is not wrapped:
|
||||
|
@ -99,7 +103,7 @@ class TypeRegistrar:
|
|||
|
||||
return inner
|
||||
|
||||
def for_obj(self, obj: PythonTypes) -> Callable:
|
||||
def for_obj(self, obj: PythonTypes) -> KQL:
|
||||
"""
|
||||
Given an object of Kusto type, retrieve the python type or function associated with the object's type, and call
|
||||
it with the given object as a parameter
|
||||
|
@ -112,7 +116,7 @@ class TypeRegistrar:
|
|||
return registered_callable(obj)
|
||||
raise ValueError("{}: no registered callable for object {} of type {}".format(self, obj, type(obj).__name__))
|
||||
|
||||
def for_type(self, t: Type[PythonTypes]) -> Callable:
|
||||
def for_type(self, t: Type[PythonTypes]) -> Callable[[Any], KQL]:
|
||||
"""
|
||||
Given a Kusto type, retrieve the associated python type or function
|
||||
|
||||
|
@ -129,3 +133,84 @@ kql_converter = TypeRegistrar("KQL Converter")
|
|||
typed_column = TypeRegistrar("Column")
|
||||
plain_expression = TypeRegistrar("Plain expression")
|
||||
aggregation_expression = TypeRegistrar("Aggregation expression")
|
||||
|
||||
|
||||
@kql_converter(KustoType.DATETIME)
|
||||
def datetime_to_kql(dt: datetime) -> KQL:
|
||||
return KQL(dt.strftime('datetime(%Y-%m-%d %H:%M:%S.%f)'))
|
||||
|
||||
|
||||
@kql_converter(KustoType.TIMESPAN)
|
||||
def timedelta_to_kql(td: timedelta) -> KQL:
|
||||
hours, remainder = divmod(td.seconds, 3600)
|
||||
minutes, seconds = divmod(remainder, 60)
|
||||
return KQL('time({days}.{hours}:{minutes}:{seconds}.{microseconds})'.format(
|
||||
days=td.days,
|
||||
hours=hours,
|
||||
minutes=minutes,
|
||||
seconds=seconds,
|
||||
microseconds=td.microseconds,
|
||||
))
|
||||
|
||||
|
||||
@kql_converter(KustoType.ARRAY, KustoType.MAPPING)
|
||||
def dynamic_to_kql(d: Union[Mapping, List, Tuple]) -> KQL:
|
||||
try:
|
||||
query = list(json.dumps(d))
|
||||
except TypeError:
|
||||
# Using exceptions as part of normal flow is not best practice, however in this case we have a good reason.
|
||||
# The given object might contain a non-primitive object somewhere inside it, and the only way to find it is to go through the entire hierarchy, which is exactly
|
||||
# what's being done in the process of json conversion.
|
||||
# Also keep in mind that exception handling in Python has no performance overhead (unlike e.g. Java).
|
||||
return build_dynamic(d)
|
||||
|
||||
# Convert square brackets to round brackets (Issue #11)
|
||||
counter = 0
|
||||
prev = ""
|
||||
for i, c in enumerate(query):
|
||||
if counter == 0:
|
||||
if c == "[":
|
||||
query[i] = "("
|
||||
elif c == "]":
|
||||
query[i] = ")"
|
||||
elif c in ['"', '\''] and prev != "\\":
|
||||
counter += 1
|
||||
elif counter > 0:
|
||||
if c in ['"', '\''] and prev != "\\":
|
||||
counter -= 1
|
||||
prev = query[i]
|
||||
assert counter == 0
|
||||
return KQL("".join(query))
|
||||
|
||||
|
||||
def build_dynamic(d: Union[Mapping, List, Tuple]) -> KQL:
|
||||
from pykusto.expressions import BaseExpression
|
||||
if isinstance(d, BaseExpression):
|
||||
return d.kql
|
||||
if isinstance(d, Mapping):
|
||||
return KQL('pack({})'.format(', '.join(map(build_dynamic, chain(*d.items())))))
|
||||
if isinstance(d, (List, Tuple)):
|
||||
return KQL('pack_array({})'.format(', '.join(map(build_dynamic, d))))
|
||||
from pykusto.expressions import to_kql
|
||||
return to_kql(d)
|
||||
|
||||
|
||||
@kql_converter(KustoType.BOOL)
|
||||
def bool_to_kql(b: bool) -> KQL:
|
||||
return KQL('true') if b else KQL('false')
|
||||
|
||||
|
||||
@kql_converter(KustoType.STRING)
|
||||
def str_to_kql(s: str) -> KQL:
|
||||
return KQL('"{}"'.format(s))
|
||||
|
||||
|
||||
@kql_converter(KustoType.INT, KustoType.LONG, KustoType.REAL)
|
||||
def number_to_kql(n: Number) -> KQL:
|
||||
return KQL(str(n))
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
@kql_converter(KustoType.NULL)
|
||||
def none_to_kql(n: None) -> KQL:
|
||||
return KQL("")
|
||||
|
|
|
@ -126,7 +126,7 @@ class MockKustoClient(KustoClient):
|
|||
databases_response: KustoResponseDataSet
|
||||
getschema_response: KustoResponseDataSet
|
||||
main_response: KustoResponseDataSet
|
||||
upon_execute: Callable
|
||||
upon_execute: Callable[[RecordedQuery], None]
|
||||
record_metadata: bool
|
||||
|
||||
def __init__(
|
||||
|
@ -137,7 +137,7 @@ class MockKustoClient(KustoClient):
|
|||
databases_response: KustoResponseDataSet = mock_databases_response([]),
|
||||
getschema_response: KustoResponseDataSet = mock_getschema_response([]),
|
||||
main_response: KustoResponseDataSet = mock_response(tuple()),
|
||||
upon_execute: Callable = None,
|
||||
upon_execute: Callable[[RecordedQuery], None] = None,
|
||||
record_metadata: bool = False
|
||||
):
|
||||
self.recorded_queries = []
|
||||
|
|
|
@ -33,7 +33,8 @@ class TestClientFetch(TestBase):
|
|||
mock_response_future = Future()
|
||||
mock_response_future.executed = False
|
||||
|
||||
def upon_execute(query):
|
||||
# noinspection PyUnusedLocal
|
||||
def upon_execute(query): # Parameter required since function is passed as Callable[[RecordedQuery], None]
|
||||
mock_response_future.result()
|
||||
mock_response_future.executed = True
|
||||
|
||||
|
@ -86,7 +87,7 @@ class TestClientFetch(TestBase):
|
|||
query_thread.join()
|
||||
# Make sure the fetch query was indeed called
|
||||
assert mock_response_future.executed
|
||||
# Before the fix the order of returned query was reveresed
|
||||
# Before the fix the order of returned query was reversed
|
||||
self.assertEqual(
|
||||
[
|
||||
RecordedQuery('test_db', '.show table test_table | project AttributeName, AttributeType | limit 10000'),
|
||||
|
|
|
@ -193,7 +193,7 @@ class TestExpressions(TestBase):
|
|||
Query().extend(foo=t.timespanField + timedelta(hours=1)).render(),
|
||||
)
|
||||
|
||||
def test_substract_timespan_from_timespan(self):
|
||||
def test_subtract_timespan_from_timespan(self):
|
||||
self.assertEqual(
|
||||
' | extend foo = timespanField - time(0.1:0:0.0)',
|
||||
Query().extend(foo=t.timespanField - timedelta(hours=1)).render(),
|
||||
|
|
|
@ -59,41 +59,41 @@ class TestFunction(TestBase):
|
|||
def test_endofday(self):
|
||||
self.assertEqual(
|
||||
" | where (endofday(dateField)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofday(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_day(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
self.assertEqual(
|
||||
" | where (endofday(dateField, 2)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofday(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_day(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
|
||||
def test_endofmonth(self):
|
||||
self.assertEqual(
|
||||
" | where (endofmonth(dateField)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofmonth(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_month(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
self.assertEqual(
|
||||
" | where (endofmonth(dateField, 2)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofmonth(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_month(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
|
||||
def test_endofweek(self):
|
||||
self.assertEqual(
|
||||
" | where (endofweek(dateField)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofweek(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_week(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
self.assertEqual(
|
||||
" | where (endofweek(dateField, 2)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofweek(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_week(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
|
||||
def test_endofyear(self):
|
||||
self.assertEqual(
|
||||
" | where (endofyear(dateField)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofyear(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_year(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
self.assertEqual(
|
||||
" | where (endofyear(dateField, 2)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.endofyear(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.end_of_year(t.dateField, 2) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
|
||||
def test_exp(self):
|
||||
|
@ -144,25 +144,25 @@ class TestFunction(TestBase):
|
|||
def test_getmonth(self):
|
||||
self.assertEqual(
|
||||
" | where (getmonth(dateField)) > 3",
|
||||
Query().where(f.getmonth(t.dateField) > 3).render()
|
||||
Query().where(f.get_month(t.dateField) > 3).render()
|
||||
)
|
||||
|
||||
def test_gettype(self):
|
||||
self.assertEqual(
|
||||
' | where (gettype(dateField)) == "datetime"',
|
||||
Query().where(f.gettype(t.dateField) == 'datetime').render()
|
||||
Query().where(f.get_type(t.dateField) == 'datetime').render()
|
||||
)
|
||||
|
||||
def test_getyear(self):
|
||||
self.assertEqual(
|
||||
" | where (getyear(dateField)) > 2019",
|
||||
Query().where(f.getyear(t.dateField) > 2019).render()
|
||||
Query().where(f.get_year(t.dateField) > 2019).render()
|
||||
)
|
||||
|
||||
def test_hourofday(self):
|
||||
self.assertEqual(
|
||||
" | where (hourofday(dateField)) == 3",
|
||||
Query().where(f.hourofday(t.dateField) == 3).render()
|
||||
Query().where(f.hour_of_day(t.dateField) == 3).render()
|
||||
)
|
||||
|
||||
def test_hash(self):
|
||||
|
@ -180,49 +180,49 @@ class TestFunction(TestBase):
|
|||
def test_isempty(self):
|
||||
self.assertEqual(
|
||||
" | where isempty(stringField)",
|
||||
Query().where(f.isempty(t.stringField)).render()
|
||||
Query().where(f.is_empty(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_isfinite(self):
|
||||
self.assertEqual(
|
||||
" | where isfinite(numField)",
|
||||
Query().where(f.isfinite(t.numField)).render()
|
||||
Query().where(f.is_finite(t.numField)).render()
|
||||
)
|
||||
|
||||
def test_isinf(self):
|
||||
self.assertEqual(
|
||||
" | where isinf(numField)",
|
||||
Query().where(f.isinf(t.numField)).render()
|
||||
Query().where(f.is_inf(t.numField)).render()
|
||||
)
|
||||
|
||||
def test_isnan(self):
|
||||
self.assertEqual(
|
||||
" | where isnan(numField)",
|
||||
Query().where(f.isnan(t.numField)).render()
|
||||
Query().where(f.is_nan(t.numField)).render()
|
||||
)
|
||||
|
||||
def test_isnotempty(self):
|
||||
self.assertEqual(
|
||||
" | where isnotempty(stringField)",
|
||||
Query().where(f.isnotempty(t.stringField)).render()
|
||||
Query().where(f.is_not_empty(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_isnotnull(self):
|
||||
self.assertEqual(
|
||||
" | where isnotnull(stringField)",
|
||||
Query().where(f.isnotnull(t.stringField)).render()
|
||||
Query().where(f.is_not_null(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_isnull(self):
|
||||
self.assertEqual(
|
||||
" | where isnull(stringField)",
|
||||
Query().where(f.isnull(t.stringField)).render()
|
||||
Query().where(f.is_null(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_isutf8(self):
|
||||
self.assertEqual(
|
||||
" | where isutf8(stringField)",
|
||||
Query().where(f.isutf8(t.stringField)).render()
|
||||
Query().where(f.is_utf8(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_log(self):
|
||||
|
@ -246,7 +246,7 @@ class TestFunction(TestBase):
|
|||
def test_loggamma(self):
|
||||
self.assertEqual(
|
||||
" | where (loggamma(numField)) < 3",
|
||||
Query().where(f.loggamma(t.numField) < 3).render()
|
||||
Query().where(f.log_gamma(t.numField) < 3).render()
|
||||
)
|
||||
|
||||
def test_make_datetime(self):
|
||||
|
@ -300,7 +300,7 @@ class TestFunction(TestBase):
|
|||
def test_parse_json_number_expression(self):
|
||||
self.assertEqual(
|
||||
' | where (todouble(parse_json(stringField).bar)) > 4',
|
||||
Query().where(f.todouble(f.parse_json(t.stringField).bar) > 4).render()
|
||||
Query().where(f.to_double(f.parse_json(t.stringField).bar) > 4).render()
|
||||
)
|
||||
|
||||
def test_parse_json_array(self):
|
||||
|
@ -341,25 +341,25 @@ class TestFunction(TestBase):
|
|||
def test_startofday(self):
|
||||
self.assertEqual(
|
||||
" | where (startofday(dateField)) > datetime(2019-07-23 00:00:00.000000)",
|
||||
Query().where(f.startofday(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
Query().where(f.start_of_day(t.dateField) > datetime(2019, 7, 23)).render()
|
||||
)
|
||||
|
||||
def test_startofmonth(self):
|
||||
self.assertEqual(
|
||||
" | where (startofmonth(dateField)) > datetime(2019-07-01 00:00:00.000000)",
|
||||
Query().where(f.startofmonth(t.dateField) > datetime(2019, 7, 1)).render()
|
||||
Query().where(f.start_of_month(t.dateField) > datetime(2019, 7, 1)).render()
|
||||
)
|
||||
|
||||
def test_startofweek(self):
|
||||
self.assertEqual(
|
||||
" | where (startofweek(dateField)) > datetime(2019-07-08 00:00:00.000000)",
|
||||
Query().where(f.startofweek(t.dateField) > datetime(2019, 7, 8)).render()
|
||||
Query().where(f.start_of_week(t.dateField) > datetime(2019, 7, 8)).render()
|
||||
)
|
||||
|
||||
def test_startofyear(self):
|
||||
self.assertEqual(
|
||||
" | where (startofyear(dateField)) > datetime(2019-01-01 00:00:00.000000)",
|
||||
Query().where(f.startofyear(t.dateField) > datetime(2019, 1, 1)).render()
|
||||
Query().where(f.start_of_year(t.dateField) > datetime(2019, 1, 1)).render()
|
||||
)
|
||||
|
||||
def test_strcat(self):
|
||||
|
@ -418,8 +418,8 @@ class TestFunction(TestBase):
|
|||
|
||||
def test_strrep(self):
|
||||
self.assertEqual(
|
||||
' | where (strrep(stringField, numField)) == "ABCABC"',
|
||||
Query().where(f.strrep(t.stringField, t.numField) == 'ABCABC').render()
|
||||
' | where (strrep(stringField, numField)) == "ABC"',
|
||||
Query().where(f.strrep(t.stringField, t.numField) == 'ABC').render()
|
||||
)
|
||||
self.assertEqual(
|
||||
' | where (strrep(stringField, numField, ",")) == "ABC,ABC"',
|
||||
|
@ -432,8 +432,8 @@ class TestFunction(TestBase):
|
|||
|
||||
def test_substring(self):
|
||||
self.assertEqual(
|
||||
' | where (substring(stringField, numField)) == "ABCABC"',
|
||||
Query().where(f.substring(t.stringField, t.numField) == 'ABCABC').render()
|
||||
' | where (substring(stringField, numField)) == "ABC"',
|
||||
Query().where(f.substring(t.stringField, t.numField) == 'ABC').render()
|
||||
)
|
||||
self.assertEqual(
|
||||
' | where (substring(stringField, numField, 4)) == "ABC,ABC"',
|
||||
|
@ -457,71 +457,71 @@ class TestFunction(TestBase):
|
|||
def test_tobool(self):
|
||||
self.assertEqual(
|
||||
" | where tobool(stringField)",
|
||||
Query().where(f.tobool(t.stringField)).render()
|
||||
Query().where(f.to_bool(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_toboolean(self):
|
||||
self.assertEqual(
|
||||
" | where toboolean(stringField)",
|
||||
Query().where(f.toboolean(t.stringField)).render()
|
||||
Query().where(f.to_boolean(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_todouble(self):
|
||||
self.assertEqual(
|
||||
" | where (todouble(stringField)) > 0.2",
|
||||
Query().where(f.todouble(t.stringField) > 0.2).render()
|
||||
Query().where(f.to_double(t.stringField) > 0.2).render()
|
||||
)
|
||||
|
||||
def test_todecimal(self):
|
||||
self.assertEqual(
|
||||
" | where (todecimal(stringField)) > 0.2",
|
||||
Query().where(f.todecimal(t.stringField) > 0.2).render()
|
||||
Query().where(f.to_decimal(t.stringField) > 0.2).render()
|
||||
)
|
||||
|
||||
def test_toint(self):
|
||||
self.assertEqual(
|
||||
" | where (toint(stringField)) > 1",
|
||||
Query().where(f.toint(t.stringField) > 1).render()
|
||||
Query().where(f.to_int(t.stringField) > 1).render()
|
||||
)
|
||||
|
||||
def test_tolong(self):
|
||||
self.assertEqual(
|
||||
" | where (tolong(stringField)) > 2222222222",
|
||||
Query().where(f.tolong(t.stringField) > 2222222222).render()
|
||||
Query().where(f.to_long(t.stringField) > 2222222222).render()
|
||||
)
|
||||
|
||||
def test_todatetime(self):
|
||||
self.assertEqual(
|
||||
" | extend foo = todatetime(stringField)",
|
||||
Query().extend(foo=f.todatetime(t.stringField)).render()
|
||||
Query().extend(foo=f.to_datetime(t.stringField)).render()
|
||||
)
|
||||
|
||||
def test_tolower(self):
|
||||
self.assertEqual(
|
||||
' | where (tolower(stringField)) == "foo"',
|
||||
Query().where(f.tolower(t.stringField) == "foo").render()
|
||||
Query().where(f.to_lower(t.stringField) == "foo").render()
|
||||
)
|
||||
|
||||
def test_toreal(self):
|
||||
self.assertEqual(
|
||||
" | where (toreal(stringField)) > 0.2",
|
||||
Query().where(f.toreal(t.stringField) > 0.2).render()
|
||||
Query().where(f.to_real(t.stringField) > 0.2).render()
|
||||
)
|
||||
|
||||
def test_toupper(self):
|
||||
self.assertEqual(
|
||||
' | where (toupper(stringField)) == "FOO"',
|
||||
Query().where(f.toupper(t.stringField) == "FOO").render()
|
||||
Query().where(f.to_upper(t.stringField) == "FOO").render()
|
||||
)
|
||||
|
||||
def test_tohex(self):
|
||||
self.assertEqual(
|
||||
' | where (tohex(256)) == "100"',
|
||||
Query().where(f.tohex(256) == "100").render()
|
||||
Query().where(f.to_hex(256) == "100").render()
|
||||
)
|
||||
|
||||
# ------------------------------------------------------
|
||||
# Aggregative Functions
|
||||
# Aggregation Functions
|
||||
# ------------------------------------------------------
|
||||
|
||||
def test_any(self):
|
||||
|
@ -573,7 +573,7 @@ class TestFunction(TestBase):
|
|||
def test_avgif(self):
|
||||
self.assertEqual(
|
||||
" | summarize avgif(numField, boolField)",
|
||||
Query().summarize(f.avgif(t.numField, t.boolField)).render()
|
||||
Query().summarize(f.avg_if(t.numField, t.boolField)).render()
|
||||
)
|
||||
|
||||
def test_bin(self):
|
||||
|
@ -631,7 +631,7 @@ class TestFunction(TestBase):
|
|||
def test_countif(self):
|
||||
self.assertEqual(
|
||||
" | summarize countif(numField == 1)",
|
||||
Query().summarize(f.countif(t.numField == 1)).render()
|
||||
Query().summarize(f.count_if(t.numField == 1)).render()
|
||||
)
|
||||
|
||||
def test_dcount(self):
|
||||
|
@ -648,7 +648,7 @@ class TestFunction(TestBase):
|
|||
def test_dcountif(self):
|
||||
self.assertEqual(
|
||||
" | summarize dcountif(stringField, boolField, 0)",
|
||||
Query().summarize(f.dcountif(t.stringField, t.boolField)).render()
|
||||
Query().summarize(f.dcount_if(t.stringField, t.boolField)).render()
|
||||
)
|
||||
|
||||
def test_make_bag(self):
|
||||
|
@ -744,7 +744,7 @@ class TestFunction(TestBase):
|
|||
def test_sumif(self):
|
||||
self.assertEqual(
|
||||
" | summarize sumif(numField, boolField)",
|
||||
Query().summarize(f.sumif(t.numField, t.boolField)).render()
|
||||
Query().summarize(f.sum_if(t.numField, t.boolField)).render()
|
||||
)
|
||||
|
||||
def test_variance(self):
|
||||
|
@ -756,7 +756,7 @@ class TestFunction(TestBase):
|
|||
def test_varianceif(self):
|
||||
self.assertEqual(
|
||||
" | summarize varianceif(numField, boolField)",
|
||||
Query().summarize(f.varianceif(t.numField, t.boolField)).render()
|
||||
Query().summarize(f.variance_if(t.numField, t.boolField)).render()
|
||||
)
|
||||
|
||||
def test_variancep(self):
|
||||
|
|
|
@ -198,7 +198,7 @@ class TestQuery(TestBase):
|
|||
def test_summarize_by_expression(self):
|
||||
self.assertEqual(
|
||||
"test_table | summarize count(stringField) by tostring(mapField)",
|
||||
Query(t).summarize(f.count(t.stringField)).by(f.tostring(t.mapField)).render(),
|
||||
Query(t).summarize(f.count(t.stringField)).by(f.to_string(t.mapField)).render(),
|
||||
)
|
||||
|
||||
def test_mv_expand(self):
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from pykusto.expressions import to_kql
|
||||
from pykusto.type_utils import TypeRegistrar, KustoType
|
||||
from pykusto.type_utils import TypeRegistrar, KustoType, KQL
|
||||
from test.test_base import TestBase
|
||||
|
||||
|
||||
|
@ -69,11 +69,11 @@ class TestUtils(TestBase):
|
|||
test_annotation = TypeRegistrar("Test annotation")
|
||||
|
||||
@test_annotation(KustoType.STRING)
|
||||
def str_annotated_1(s: str) -> str:
|
||||
return "response to " + s
|
||||
def str_annotated_1(s: str) -> KQL:
|
||||
return KQL("response to " + s)
|
||||
|
||||
def str_annotated_2(s: str) -> str:
|
||||
return "response to " + s
|
||||
def str_annotated_2(s: str) -> KQL:
|
||||
return KQL("response to " + s)
|
||||
|
||||
self.assertRaises(
|
||||
TypeError("Test annotation: type already registered: string"),
|
||||
|
|
Загрузка…
Ссылка в новой задаче