tinybird-cli 5.9.1.dev1__tar.gz → 5.9.1.dev3__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.
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/PKG-INFO +8 -2
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/__cli__.py +2 -2
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/ch_utils/engine.py +21 -1
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/datafile.py +11 -7
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/feedback_manager.py +3 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/sql.py +31 -3
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/sql_template.py +22 -5
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/common.py +4 -4
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird_cli.egg-info/PKG-INFO +8 -2
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/setup.cfg +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/check_pypi.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/client.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/config.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/connectors.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/context.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/datatypes.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/git_settings.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/sql_toolset.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/syncasync.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/token.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tornado_template.py +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird_cli.egg-info/SOURCES.txt +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird_cli.egg-info/dependency_links.txt +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird_cli.egg-info/entry_points.txt +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird_cli.egg-info/requires.txt +0 -0
- {tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinybird-cli
|
|
3
|
-
Version: 5.9.1.
|
|
3
|
+
Version: 5.9.1.dev3
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli/introduction.html
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,10 +18,16 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
-
5.9.1.
|
|
21
|
+
5.9.1.dev3
|
|
22
|
+
***********
|
|
23
|
+
|
|
24
|
+
- `Fixed` Correctly parse lambda expressions in indexes
|
|
25
|
+
|
|
26
|
+
5.9.1.dev2
|
|
22
27
|
***********
|
|
23
28
|
|
|
24
29
|
- `Changed` Upgrade clickhouse-toolset to 0.32.dev0
|
|
30
|
+
- `Added` new "File not found" error to `tb check` when including files from missing paths.
|
|
25
31
|
|
|
26
32
|
5.9.0
|
|
27
33
|
***********
|
|
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
|
|
|
4
4
|
__url__ = 'https://www.tinybird.co/docs/cli/introduction.html'
|
|
5
5
|
__author__ = 'Tinybird'
|
|
6
6
|
__author_email__ = 'support@tinybird.co'
|
|
7
|
-
__version__ = '5.9.1.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '5.9.1.dev3'
|
|
8
|
+
__revision__ = '6e69bc3'
|
|
@@ -4,7 +4,14 @@ from collections import defaultdict
|
|
|
4
4
|
from dataclasses import asdict
|
|
5
5
|
from typing import Any, Callable, Dict, Iterable, List, Optional
|
|
6
6
|
|
|
7
|
-
from ..sql import
|
|
7
|
+
from ..sql import (
|
|
8
|
+
TableIndex,
|
|
9
|
+
TableProjection,
|
|
10
|
+
col_name,
|
|
11
|
+
engine_replicated_to_local,
|
|
12
|
+
parse_indexes_structure,
|
|
13
|
+
parse_table_structure,
|
|
14
|
+
)
|
|
8
15
|
|
|
9
16
|
DEFAULT_EMPTY_PARAMETERS = ["ttl", "partition_key", "sorting_key"]
|
|
10
17
|
DEFAULT_JOIN_EMPTY_PARAMETERS = ["join_strictness", "join_type", "key_columns"]
|
|
@@ -237,6 +244,10 @@ class TableDetails:
|
|
|
237
244
|
def indexes(self) -> List[TableIndex]:
|
|
238
245
|
return _parse_indexes(str(self.details.get("create_table_query", "")))
|
|
239
246
|
|
|
247
|
+
@property
|
|
248
|
+
def projections(self) -> List[TableProjection]:
|
|
249
|
+
return _parse_projections(self.details.get("create_table_query", ""))
|
|
250
|
+
|
|
240
251
|
def to_json(self, exclude: Optional[List[str]] = None, include_empty_details: bool = False):
|
|
241
252
|
# name, database are not exported since they are not part of the engine
|
|
242
253
|
d: Dict[str, Any] = {
|
|
@@ -833,3 +844,12 @@ def _parse_indexes(create_table_query_expr: str) -> List[TableIndex]:
|
|
|
833
844
|
return []
|
|
834
845
|
|
|
835
846
|
return parse_indexes_structure(indexes)
|
|
847
|
+
|
|
848
|
+
|
|
849
|
+
def _parse_projections(create_table_query_expr: str) -> List[TableProjection]:
|
|
850
|
+
return [
|
|
851
|
+
TableProjection(name, expr)
|
|
852
|
+
for name, expr in re.findall(
|
|
853
|
+
r"PROJECTION\s+(\w+)\s*\(((?:[^()]|\((?:[^()]|\([^()]*\))*\))*)\)", create_table_query_expr
|
|
854
|
+
)
|
|
855
|
+
]
|
|
@@ -278,7 +278,9 @@ class ParseException(Exception):
|
|
|
278
278
|
|
|
279
279
|
|
|
280
280
|
class IncludeFileNotFoundException(Exception):
|
|
281
|
-
|
|
281
|
+
def __init__(self, err: str, lineno: int = -1):
|
|
282
|
+
self.lineno: int = lineno
|
|
283
|
+
super().__init__(err)
|
|
282
284
|
|
|
283
285
|
|
|
284
286
|
class ValidationException(Exception):
|
|
@@ -584,7 +586,7 @@ class Deployment:
|
|
|
584
586
|
self.cli_git_release.validate_local_for_release(self.current_release, check_outdated=check_outdated)
|
|
585
587
|
click.echo(FeedbackManager.info_deployment_detecting_changes_header())
|
|
586
588
|
commit = self.cli_git_release.get_main_branch_commit() if use_main else self.current_release["commit"]
|
|
587
|
-
diffs = self.cli_git_release.diff_datafiles(commit)
|
|
589
|
+
diffs = self.cli_git_release.diff_datafiles(commit) # type: ignore
|
|
588
590
|
click.echo(
|
|
589
591
|
FeedbackManager.info_git_release_diffs(
|
|
590
592
|
workspace=self.current_ws["name"],
|
|
@@ -863,6 +865,8 @@ def parse_pipe(
|
|
|
863
865
|
raise click.ClickException(
|
|
864
866
|
FeedbackManager.error_parsing_node_with_unclosed_if(node=e.node, pipe=filename, lineno=e.lineno, sql=e.sql)
|
|
865
867
|
)
|
|
868
|
+
except IncludeFileNotFoundException as e:
|
|
869
|
+
raise click.ClickException(FeedbackManager.error_not_found_include(filename=e, lineno=e.lineno))
|
|
866
870
|
except ModuleNotFoundError:
|
|
867
871
|
pass
|
|
868
872
|
return doc
|
|
@@ -1110,7 +1114,7 @@ def parse(
|
|
|
1110
1114
|
StringIO(Template(file.read()).safe_substitute(attrs), newline=None)
|
|
1111
1115
|
)
|
|
1112
1116
|
except FileNotFoundError:
|
|
1113
|
-
raise IncludeFileNotFoundException(f)
|
|
1117
|
+
raise IncludeFileNotFoundException(f, lineno)
|
|
1114
1118
|
|
|
1115
1119
|
def version(*args: str, **kwargs: Any) -> None:
|
|
1116
1120
|
if len(args) < 1:
|
|
@@ -1298,7 +1302,7 @@ def parse(
|
|
|
1298
1302
|
else:
|
|
1299
1303
|
raise ValidationException(f"Validation error, found {line} in line {str(lineno)}: {str(e)}", lineno=lineno)
|
|
1300
1304
|
except IncludeFileNotFoundException as e:
|
|
1301
|
-
raise e
|
|
1305
|
+
raise IncludeFileNotFoundException(str(e), lineno=lineno)
|
|
1302
1306
|
except Exception as e:
|
|
1303
1307
|
traceback.print_tb(e.__traceback__)
|
|
1304
1308
|
raise ParseException(f"Unexpected error: {e}", lineno=lineno)
|
|
@@ -2114,7 +2118,7 @@ class PipeCheckerRunnerResponse:
|
|
|
2114
2118
|
|
|
2115
2119
|
|
|
2116
2120
|
class PipeCheckerRunner:
|
|
2117
|
-
checker_stream_result_class = unittest.runner._WritelnDecorator
|
|
2121
|
+
checker_stream_result_class = unittest.runner._WritelnDecorator
|
|
2118
2122
|
|
|
2119
2123
|
def __init__(self, pipe_name: str, host: str):
|
|
2120
2124
|
self.pipe_name = pipe_name
|
|
@@ -2277,7 +2281,7 @@ class PipeCheckerRunner:
|
|
|
2277
2281
|
)
|
|
2278
2282
|
|
|
2279
2283
|
result = PipeCheckerTextTestResult(
|
|
2280
|
-
self.checker_stream_result_class(sys.stdout), descriptions=True, verbosity=2, custom_output=custom_output
|
|
2284
|
+
self.checker_stream_result_class(sys.stdout), descriptions=True, verbosity=2, custom_output=custom_output # type: ignore
|
|
2281
2285
|
)
|
|
2282
2286
|
result.failfast = failfast
|
|
2283
2287
|
suite.run(result)
|
|
@@ -3985,7 +3989,7 @@ async def build_graph(
|
|
|
3985
3989
|
mapped_workspaces.append(
|
|
3986
3990
|
workspace_map.get(shared_with)
|
|
3987
3991
|
if workspace_map.get(shared_with, None) is not None
|
|
3988
|
-
else shared_with
|
|
3992
|
+
else shared_with # type: ignore
|
|
3989
3993
|
)
|
|
3990
3994
|
r["shared_with"] = mapped_workspaces
|
|
3991
3995
|
|
|
@@ -242,6 +242,9 @@ class FeedbackManager:
|
|
|
242
242
|
error_deleted_include = error_message(
|
|
243
243
|
"Related include file {include_file} was deleted and it's used in {filename}. Delete or remove dependency from {filename}."
|
|
244
244
|
)
|
|
245
|
+
error_not_found_include = error_message(
|
|
246
|
+
"Included file {filename} at line {lineno} not found. Check if the file exists and the path is correct."
|
|
247
|
+
)
|
|
245
248
|
error_branch = error_message(
|
|
246
249
|
"Branch {branch} not found. use 'tb branch ls' to list your Branches, make sure you are authenticated using the right workspace token"
|
|
247
250
|
)
|
|
@@ -38,11 +38,37 @@ class TableIndex:
|
|
|
38
38
|
return f"CLEAR INDEX IF EXISTS {self.name}"
|
|
39
39
|
|
|
40
40
|
|
|
41
|
+
@dataclass
|
|
42
|
+
class TableProjection:
|
|
43
|
+
"""Defines a CH table PROJECTION"""
|
|
44
|
+
|
|
45
|
+
name: str
|
|
46
|
+
expr: str
|
|
47
|
+
|
|
48
|
+
def to_datafile(self):
|
|
49
|
+
return f"{self.name} ({self.expr})"
|
|
50
|
+
|
|
51
|
+
def to_sql(self):
|
|
52
|
+
return f"PROJECTION {self.to_datafile()}"
|
|
53
|
+
|
|
54
|
+
def add_index_sql(self):
|
|
55
|
+
return f"ADD {self.to_sql()}"
|
|
56
|
+
|
|
57
|
+
def drop_index_sql(self):
|
|
58
|
+
return f"DROP PROJECTION IF EXISTS {self.name}"
|
|
59
|
+
|
|
60
|
+
def materialize_index_sql(self):
|
|
61
|
+
return f"MATERIALIZE PROJECTION IF EXISTS {self.name}"
|
|
62
|
+
|
|
63
|
+
def clear_index_sql(self):
|
|
64
|
+
return f"CLEAR PROJECTION IF EXISTS {self.name}"
|
|
65
|
+
|
|
66
|
+
|
|
41
67
|
def as_subquery(sql: str) -> str:
|
|
42
68
|
return f"""(\n{sql}\n)"""
|
|
43
69
|
|
|
44
70
|
|
|
45
|
-
def get_format(sql: str) -> str:
|
|
71
|
+
def get_format(sql: str) -> Optional[str]:
|
|
46
72
|
"""
|
|
47
73
|
retrieves FORMAT from CH sql
|
|
48
74
|
>>> get_format('select * from test')
|
|
@@ -211,7 +237,7 @@ def format_parse_error(
|
|
|
211
237
|
return message
|
|
212
238
|
|
|
213
239
|
|
|
214
|
-
def parse_indexes_structure(indexes: List[str]) -> List[TableIndex]:
|
|
240
|
+
def parse_indexes_structure(indexes: Optional[List[str]]) -> List[TableIndex]:
|
|
215
241
|
"""
|
|
216
242
|
>>> parse_indexes_structure(["index_name a TYPE set(100) GRANULARITY 100", "index_name_bf mapValues(d) TYPE bloom_filter(0.001) GRANULARITY 16"])
|
|
217
243
|
[TableIndex(name='index_name', expr='a', type_full='set(100)', granularity='100'), TableIndex(name='index_name_bf', expr='mapValues(d)', type_full='bloom_filter(0.001)', granularity='16')]
|
|
@@ -239,6 +265,8 @@ def parse_indexes_structure(indexes: List[str]) -> List[TableIndex]:
|
|
|
239
265
|
ValueError: invalid INDEX format. Usage: `name expr TYPE type_full GRANULARITY granularity`
|
|
240
266
|
>>> parse_indexes_structure(["my_index m['key'] TYPE ngrambf_v1(1, 1024, 1, 42) GRANULARITY 1"])
|
|
241
267
|
[TableIndex(name='my_index', expr="m['key']", type_full='ngrambf_v1(1, 1024, 1, 42)', granularity='1')]
|
|
268
|
+
>>> parse_indexes_structure(["my_index_lambda arrayMap(x -> tupleElement(x,'message'), column_name) TYPE ngrambf_v1(1, 1024, 1, 42) GRANULARITY 1"])
|
|
269
|
+
[TableIndex(name='my_index_lambda', expr="arrayMap(x -> tupleElement(x,'message'), column_name)", type_full='ngrambf_v1(1, 1024, 1, 42)', granularity='1')]
|
|
242
270
|
>>> parse_indexes_structure(["ip_range_minmax_idx (toIPv6(ip_range_start), toIPv6(ip_range_end)) TYPE minmax GRANULARITY 1"])
|
|
243
271
|
[TableIndex(name='ip_range_minmax_idx', expr='(toIPv6(ip_range_start), toIPv6(ip_range_end))', type_full='minmax', granularity='1')]
|
|
244
272
|
"""
|
|
@@ -253,7 +281,7 @@ def parse_indexes_structure(indexes: List[str]) -> List[TableIndex]:
|
|
|
253
281
|
raise ValueError("invalid INDEX format. Usage: `name expr TYPE type_full GRANULARITY granularity`")
|
|
254
282
|
|
|
255
283
|
match = re.match(
|
|
256
|
-
r"(\w+)\s+([\w\s*\[\]\*\(\),\'\"
|
|
284
|
+
r"(\w+)\s+([\w\s*\[\]\*\(\),\'\"-><.]+)\s+TYPE\s+(\w+)(?:\(([\w\s*.,]+)\))?(?:\s+GRANULARITY\s+(\d+))?",
|
|
257
285
|
index,
|
|
258
286
|
)
|
|
259
287
|
if match:
|
|
@@ -1619,8 +1619,10 @@ def get_var_data(content, node_id=None): # noqa: C901
|
|
|
1619
1619
|
|
|
1620
1620
|
kwargs = {}
|
|
1621
1621
|
for x in node.keywords:
|
|
1622
|
-
|
|
1623
|
-
|
|
1622
|
+
value = node_to_value(x.value)
|
|
1623
|
+
kwargs[x.arg] = value
|
|
1624
|
+
if x.arg == "default":
|
|
1625
|
+
kwargs["default"] = check_default_value(value)
|
|
1624
1626
|
if func in VALID_CUSTOM_FUNCTION_NAMES:
|
|
1625
1627
|
# Type definition here is set to 'String' because it comes from a
|
|
1626
1628
|
# `defined(variable)` expression that does not contain any type hint.
|
|
@@ -1628,11 +1630,15 @@ def get_var_data(content, node_id=None): # noqa: C901
|
|
|
1628
1630
|
# args[0] check is used to avoid adding unnamed parameters found in
|
|
1629
1631
|
# templates like: `split_to_array('')`
|
|
1630
1632
|
if len(args) > 0 and args[0] not in vars and args[0]:
|
|
1631
|
-
vars[args[0]] = {
|
|
1633
|
+
vars[args[0]] = {
|
|
1634
|
+
"type": "String",
|
|
1635
|
+
"default": None,
|
|
1636
|
+
"used_in": "function_call",
|
|
1637
|
+
}
|
|
1632
1638
|
elif func == "Array":
|
|
1633
1639
|
if "default" not in kwargs:
|
|
1634
1640
|
default = kwargs.get("default", args[2] if len(args) > 2 and args[2] else None)
|
|
1635
|
-
kwargs["default"] = default
|
|
1641
|
+
kwargs["default"] = check_default_value(default)
|
|
1636
1642
|
if len(args):
|
|
1637
1643
|
vars[args[0]] = {
|
|
1638
1644
|
"type": f"Array({args[1]})" if len(args) > 1 else "Array(String)",
|
|
@@ -1644,9 +1650,11 @@ def get_var_data(content, node_id=None): # noqa: C901
|
|
|
1644
1650
|
# if this is a cast use the function name to get the type
|
|
1645
1651
|
if "default" not in kwargs:
|
|
1646
1652
|
default = kwargs.get("default", args[1] if len(args) > 1 else None)
|
|
1647
|
-
kwargs["default"] = default
|
|
1653
|
+
kwargs["default"] = check_default_value(default)
|
|
1648
1654
|
try:
|
|
1649
1655
|
vars[args[0]] = {"type": func, **kwargs}
|
|
1656
|
+
if "default" in kwargs:
|
|
1657
|
+
kwargs["default"] = check_default_value(kwargs["default"])
|
|
1650
1658
|
except TypeError as e:
|
|
1651
1659
|
logging.exception(f"pipe parsing problem {content} (node '{node_id}'): {e}")
|
|
1652
1660
|
except Exception as e:
|
|
@@ -1665,6 +1673,13 @@ def get_var_data(content, node_id=None): # noqa: C901
|
|
|
1665
1673
|
|
|
1666
1674
|
return vars
|
|
1667
1675
|
|
|
1676
|
+
def check_default_value(value):
|
|
1677
|
+
if isinstance(value, int):
|
|
1678
|
+
MAX_SAFE_INTEGER = 9007199254740991
|
|
1679
|
+
if value > MAX_SAFE_INTEGER:
|
|
1680
|
+
return str(value)
|
|
1681
|
+
return value
|
|
1682
|
+
|
|
1668
1683
|
def parse_content(content, retries=0):
|
|
1669
1684
|
try:
|
|
1670
1685
|
parsed = ast.parse(content)
|
|
@@ -1744,6 +1759,8 @@ def get_var_names_and_types(t, node_id=None): # noqa: C901
|
|
|
1744
1759
|
[{'name': 'symbol_id', 'type': 'Int128', 'description': 'Symbol Id', 'required': True, 'default': 11111}, {'name': 'user_id', 'type': 'Int256', 'description': 'User Id', 'default': 3555}]
|
|
1745
1760
|
>>> get_var_names_and_types(Template("SELECT now() > {{DateTime64(timestamp, '2020-09-09 10:10:10.000')}}"))
|
|
1746
1761
|
[{'name': 'timestamp', 'type': 'DateTime64', 'default': '2020-09-09 10:10:10.000'}]
|
|
1762
|
+
>>> get_var_names_and_types(Template("SELECT * FROM filter_value WHERE symbol = {{Int64(symbol_id, 9223372036854775807)}}"))
|
|
1763
|
+
[{'name': 'symbol_id', 'type': 'Int64', 'default': '9223372036854775807'}]
|
|
1747
1764
|
"""
|
|
1748
1765
|
try:
|
|
1749
1766
|
|
|
@@ -1214,12 +1214,12 @@ def autocomplete_topics(ctx: Context, args, incomplete):
|
|
|
1214
1214
|
|
|
1215
1215
|
|
|
1216
1216
|
def validate_datasource_name(name):
|
|
1217
|
-
if not isinstance(name, str) or
|
|
1217
|
+
if not isinstance(name, str) or name == "":
|
|
1218
1218
|
raise CLIException(FeedbackManager.error_datasource_name())
|
|
1219
1219
|
|
|
1220
1220
|
|
|
1221
1221
|
def validate_connection_id(connection_id):
|
|
1222
|
-
if not isinstance(connection_id, str) or
|
|
1222
|
+
if not isinstance(connection_id, str) or connection_id == "":
|
|
1223
1223
|
raise CLIException(FeedbackManager.error_datasource_connection_id())
|
|
1224
1224
|
|
|
1225
1225
|
|
|
@@ -1235,7 +1235,7 @@ def validate_kafka_group(group):
|
|
|
1235
1235
|
|
|
1236
1236
|
def validate_kafka_auto_offset_reset(auto_offset_reset):
|
|
1237
1237
|
valid_values = {"latest", "earliest", "none"}
|
|
1238
|
-
if not
|
|
1238
|
+
if auto_offset_reset not in valid_values:
|
|
1239
1239
|
raise CLIException(FeedbackManager.error_kafka_auto_offset_reset())
|
|
1240
1240
|
|
|
1241
1241
|
|
|
@@ -1588,7 +1588,7 @@ async def try_update_config_with_remote(
|
|
|
1588
1588
|
def ask_for_admin_token_interactively(ui_host: str, default_token: Optional[str]) -> str:
|
|
1589
1589
|
return (
|
|
1590
1590
|
click.prompt(
|
|
1591
|
-
f"\nCopy the \"admin your@email\" token from {ui_host}/tokens and paste it here {
|
|
1591
|
+
f"\nCopy the \"admin your@email\" token from {ui_host}/tokens and paste it here { 'OR press enter to use the token from .tinyb file' if default_token else ''}",
|
|
1592
1592
|
hide_input=True,
|
|
1593
1593
|
show_default=False,
|
|
1594
1594
|
default=default_token,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tinybird-cli
|
|
3
|
-
Version: 5.9.1.
|
|
3
|
+
Version: 5.9.1.dev3
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/cli/introduction.html
|
|
6
6
|
Author: Tinybird
|
|
@@ -18,10 +18,16 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
18
18
|
Changelog
|
|
19
19
|
----------
|
|
20
20
|
|
|
21
|
-
5.9.1.
|
|
21
|
+
5.9.1.dev3
|
|
22
|
+
***********
|
|
23
|
+
|
|
24
|
+
- `Fixed` Correctly parse lambda expressions in indexes
|
|
25
|
+
|
|
26
|
+
5.9.1.dev2
|
|
22
27
|
***********
|
|
23
28
|
|
|
24
29
|
- `Changed` Upgrade clickhouse-toolset to 0.32.dev0
|
|
30
|
+
- `Added` new "File not found" error to `tb check` when including files from missing paths.
|
|
25
31
|
|
|
26
32
|
5.9.0
|
|
27
33
|
***********
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/tinyunit/tinyunit.py
RENAMED
|
File without changes
|
{tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/tinyunit/tinyunit_lib.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird/tb_cli_modules/workspace_members.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-cli-5.9.1.dev1 → tinybird-cli-5.9.1.dev3}/tinybird_cli.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|