tinybird 0.0.1.dev19__py3-none-any.whl → 0.0.1.dev21__py3-none-any.whl
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.
Potentially problematic release.
This version of tinybird might be problematic. Click here for more details.
- tinybird/client.py +2 -2
- tinybird/config.py +1 -1
- tinybird/feedback_manager.py +8 -30
- tinybird/prompts.py +2 -2
- tinybird/tb/__cli__.py +2 -2
- tinybird/tb/modules/auth.py +1 -1
- tinybird/tb/modules/build.py +10 -78
- tinybird/tb/modules/cicd.py +1 -1
- tinybird/tb/modules/cli.py +9 -837
- tinybird/tb/modules/common.py +1 -55
- tinybird/tb/modules/connection.py +1 -1
- tinybird/tb/modules/create.py +26 -13
- tinybird/tb/modules/datafile/build.py +142 -971
- tinybird/tb/modules/datafile/build_common.py +1 -1
- tinybird/tb/modules/datafile/build_datasource.py +1 -1
- tinybird/tb/modules/datafile/build_pipe.py +1 -1
- tinybird/tb/modules/datafile/common.py +11 -11
- tinybird/tb/modules/datafile/diff.py +1 -1
- tinybird/tb/modules/datafile/fixture.py +1 -1
- tinybird/tb/modules/datafile/format_common.py +0 -7
- tinybird/tb/modules/datafile/format_datasource.py +0 -2
- tinybird/tb/modules/datafile/format_pipe.py +0 -2
- tinybird/tb/modules/datafile/parse_datasource.py +1 -1
- tinybird/tb/modules/datafile/parse_pipe.py +1 -1
- tinybird/tb/modules/datafile/pull.py +1 -1
- tinybird/tb/modules/datasource.py +4 -75
- tinybird/tb/modules/feedback_manager.py +1048 -0
- tinybird/tb/modules/fmt.py +1 -1
- tinybird/tb/modules/job.py +1 -1
- tinybird/tb/modules/llm.py +15 -26
- tinybird/tb/modules/local.py +33 -32
- tinybird/tb/modules/local_common.py +2 -1
- tinybird/tb/modules/login.py +8 -8
- tinybird/tb/modules/mock.py +19 -9
- tinybird/tb/modules/pipe.py +4 -126
- tinybird/tb/modules/{build_shell.py → shell.py} +9 -21
- tinybird/tb/modules/table.py +88 -5
- tinybird/tb/modules/tag.py +2 -2
- tinybird/tb/modules/test.py +13 -15
- tinybird/tb/modules/tinyunit/tinyunit.py +1 -1
- tinybird/tb/modules/token.py +2 -2
- tinybird/tb/modules/watch.py +72 -0
- tinybird/tb/modules/workspace.py +1 -1
- tinybird/tb/modules/workspace_members.py +1 -1
- {tinybird-0.0.1.dev19.dist-info → tinybird-0.0.1.dev21.dist-info}/METADATA +1 -1
- tinybird-0.0.1.dev21.dist-info/RECORD +76 -0
- tinybird-0.0.1.dev19.dist-info/RECORD +0 -74
- {tinybird-0.0.1.dev19.dist-info → tinybird-0.0.1.dev21.dist-info}/WHEEL +0 -0
- {tinybird-0.0.1.dev19.dist-info → tinybird-0.0.1.dev21.dist-info}/entry_points.txt +0 -0
- {tinybird-0.0.1.dev19.dist-info → tinybird-0.0.1.dev21.dist-info}/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
|
|
3
3
|
import click
|
|
4
4
|
|
|
5
5
|
from tinybird.client import DoesNotExistException, TinyB
|
|
6
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
6
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
async def update_tags(resource_id: str, resource_name: str, resource_type: str, tags: List[str], tb_client: TinyB):
|
|
@@ -6,8 +6,8 @@ from typing import Any, Dict, List, Optional
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
8
8
|
from tinybird.client import DoesNotExistException, TinyB
|
|
9
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
10
9
|
from tinybird.tb.modules.datafile.common import PREVIEW_CONNECTOR_SERVICES, ImportReplacements
|
|
10
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
async def new_ds(
|
|
@@ -9,11 +9,11 @@ import requests
|
|
|
9
9
|
from croniter import croniter
|
|
10
10
|
|
|
11
11
|
from tinybird.client import DoesNotExistException, TinyB
|
|
12
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
13
12
|
from tinybird.tb.modules.common import getenv_bool, requests_delete, requests_get, wait_job
|
|
14
13
|
from tinybird.tb.modules.datafile.common import ON_DEMAND, CopyModes, CopyParameters, PipeNodeTypes, PipeTypes
|
|
15
14
|
from tinybird.tb.modules.datafile.pipe_checker import PipeCheckerRunner
|
|
16
15
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
16
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
17
17
|
from tinybird.tb.modules.table import format_pretty_table
|
|
18
18
|
|
|
19
19
|
|
|
@@ -20,9 +20,9 @@ import click
|
|
|
20
20
|
from mypy_extensions import KwArg, VarArg
|
|
21
21
|
|
|
22
22
|
from tinybird.ch_utils.engine import ENABLED_ENGINES
|
|
23
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
24
23
|
from tinybird.tb.modules.datafile.exceptions import IncludeFileNotFoundException, ParseException, ValidationException
|
|
25
24
|
from tinybird.tb.modules.exceptions import CLIPipeException
|
|
25
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
26
26
|
|
|
27
27
|
# Code from sql.py has been duplicated so I can change it without breaking absolutely everything in the app
|
|
28
28
|
# I'll try not to make logic changes, just error reporting changes
|
|
@@ -33,7 +33,7 @@ class DatafileSyntaxError(Exception):
|
|
|
33
33
|
def __init__(self, message: str, lineno: int, pos: int, hint: Optional[str] = None):
|
|
34
34
|
super().__init__(message)
|
|
35
35
|
self.message = message
|
|
36
|
-
self.context = None
|
|
36
|
+
self.context: Optional[str] = None
|
|
37
37
|
self.hint = hint
|
|
38
38
|
self.lineno = lineno
|
|
39
39
|
self.pos = pos
|
|
@@ -331,12 +331,12 @@ def parse_indexes_structure(indexes: Optional[List[str]]) -> List[TableIndex]:
|
|
|
331
331
|
return parsed_indices
|
|
332
332
|
|
|
333
333
|
|
|
334
|
-
def clean_comments_rstrip_keep_empty_lines(schema_to_clean: Optional[str]) ->
|
|
334
|
+
def clean_comments_rstrip_keep_empty_lines(schema_to_clean: Optional[str]) -> str:
|
|
335
335
|
"""Remove the comments from the schema
|
|
336
336
|
If the comments are between backticks, they will not be removed.
|
|
337
337
|
Lines that are empty after removing comments are also removed. Lines are only rstripped of whitespaces
|
|
338
|
-
>>> clean_comments_rstrip_keep_empty_lines(None)
|
|
339
|
-
|
|
338
|
+
>>> clean_comments_rstrip_keep_empty_lines(None)
|
|
339
|
+
''
|
|
340
340
|
>>> clean_comments_rstrip_keep_empty_lines('')
|
|
341
341
|
''
|
|
342
342
|
>>> clean_comments_rstrip_keep_empty_lines(' ')
|
|
@@ -394,7 +394,7 @@ def clean_comments_rstrip_keep_empty_lines(schema_to_clean: Optional[str]) -> Tu
|
|
|
394
394
|
return line
|
|
395
395
|
|
|
396
396
|
if schema_to_clean is None:
|
|
397
|
-
return
|
|
397
|
+
return ""
|
|
398
398
|
|
|
399
399
|
cleaned_schema = ""
|
|
400
400
|
for line in schema_to_clean.splitlines():
|
|
@@ -1421,7 +1421,7 @@ def parse(
|
|
|
1421
1421
|
# When the error is in a multiline block, add the start lineno to the error lineno so the error location is in
|
|
1422
1422
|
# respect to the whole file
|
|
1423
1423
|
if parser_state.multiline:
|
|
1424
|
-
e.lineno += parser_state.start_lineno
|
|
1424
|
+
e.lineno += parser_state.start_lineno or 0
|
|
1425
1425
|
raise e
|
|
1426
1426
|
except ParseException as e:
|
|
1427
1427
|
raise ParseException(str(e), lineno=lineno)
|
|
@@ -1650,7 +1650,7 @@ def find_file_by_name(
|
|
|
1650
1650
|
name: str,
|
|
1651
1651
|
verbose: bool = False,
|
|
1652
1652
|
is_raw: bool = False,
|
|
1653
|
-
|
|
1653
|
+
vendor_paths: Optional[List[Tuple[str, str]]] = None,
|
|
1654
1654
|
resource: Optional[Dict] = None,
|
|
1655
1655
|
):
|
|
1656
1656
|
f = Path(folder)
|
|
@@ -1675,9 +1675,9 @@ def find_file_by_name(
|
|
|
1675
1675
|
return token, None
|
|
1676
1676
|
|
|
1677
1677
|
# look for the file in subdirectories if it's not found in datasources folder
|
|
1678
|
-
if
|
|
1678
|
+
if vendor_paths:
|
|
1679
1679
|
_resource = None
|
|
1680
|
-
for wk_name, wk_path in
|
|
1680
|
+
for wk_name, wk_path in vendor_paths:
|
|
1681
1681
|
file = None
|
|
1682
1682
|
if name.startswith(f"{wk_name}."):
|
|
1683
1683
|
file, _resource = find_file_by_name(
|
|
@@ -1692,7 +1692,7 @@ def find_file_by_name(
|
|
|
1692
1692
|
name,
|
|
1693
1693
|
verbose=verbose,
|
|
1694
1694
|
is_raw=True,
|
|
1695
|
-
|
|
1695
|
+
vendor_paths=vendor_paths,
|
|
1696
1696
|
resource=resource,
|
|
1697
1697
|
)
|
|
1698
1698
|
return f, raw
|
|
@@ -23,12 +23,12 @@ import sys
|
|
|
23
23
|
import click
|
|
24
24
|
|
|
25
25
|
from tinybird.client import TinyB
|
|
26
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
27
26
|
from tinybird.sql_template_fmt import DEFAULT_FMT_LINE_LENGTH
|
|
28
27
|
from tinybird.tb.modules.datafile.common import get_name_version, get_project_filenames, is_file_a_datasource, peek
|
|
29
28
|
from tinybird.tb.modules.datafile.format_datasource import format_datasource
|
|
30
29
|
from tinybird.tb.modules.datafile.format_pipe import format_pipe
|
|
31
30
|
from tinybird.tb.modules.datafile.pull import folder_pull
|
|
31
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
async def diff_files(
|
|
@@ -18,7 +18,7 @@ def build_fixture_name(filename: str, datasource_name: str, datasource_content:
|
|
|
18
18
|
str: A unique fixture name combining a hash of the inputs with the datasource name
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
doc = parse_datasource(filename, datasource_content)
|
|
21
|
+
doc = parse_datasource(filename, content=datasource_content)
|
|
22
22
|
schema = doc.nodes[0].get("schema", "").strip()
|
|
23
23
|
# Combine all inputs into a single string
|
|
24
24
|
combined = f"{datasource_name}{schema}"
|
|
@@ -20,13 +20,6 @@ def format_description(file_parts: List[str], doc: Any) -> List[str]:
|
|
|
20
20
|
return file_parts
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def format_sources(file_parts: List[str], doc: Datafile) -> List[str]:
|
|
24
|
-
for source in doc.sources:
|
|
25
|
-
file_parts.append(f"SOURCE {source}")
|
|
26
|
-
file_parts.append(DATAFILE_NEW_LINE)
|
|
27
|
-
return file_parts
|
|
28
|
-
|
|
29
|
-
|
|
30
23
|
def format_maintainer(file_parts: List[str], doc: Datafile) -> List[str]:
|
|
31
24
|
maintainer = doc.maintainer if doc.maintainer is not None else ""
|
|
32
25
|
if maintainer:
|
|
@@ -9,7 +9,6 @@ from tinybird.tb.modules.datafile.format_common import (
|
|
|
9
9
|
format_description,
|
|
10
10
|
format_include,
|
|
11
11
|
format_maintainer,
|
|
12
|
-
format_sources,
|
|
13
12
|
format_tags,
|
|
14
13
|
format_tokens,
|
|
15
14
|
)
|
|
@@ -61,7 +60,6 @@ async def format_datasource(
|
|
|
61
60
|
format_import_settings(file_parts, doc.nodes[0])
|
|
62
61
|
format_shared_with(file_parts, doc)
|
|
63
62
|
else:
|
|
64
|
-
format_sources(file_parts, doc)
|
|
65
63
|
format_maintainer(file_parts, doc)
|
|
66
64
|
format_description(file_parts, doc)
|
|
67
65
|
format_tokens(file_parts, doc)
|
|
@@ -17,7 +17,6 @@ from tinybird.tb.modules.datafile.format_common import (
|
|
|
17
17
|
DATAFILE_NEW_LINE,
|
|
18
18
|
format_description,
|
|
19
19
|
format_maintainer,
|
|
20
|
-
format_sources,
|
|
21
20
|
format_tags,
|
|
22
21
|
format_tokens,
|
|
23
22
|
)
|
|
@@ -140,7 +139,6 @@ async def format_pipe(
|
|
|
140
139
|
doc = parse_pipe(filename, replace_includes=replace_includes, skip_eval=skip_eval, content=content)
|
|
141
140
|
|
|
142
141
|
file_parts: List[str] = []
|
|
143
|
-
format_sources(file_parts, doc)
|
|
144
142
|
format_maintainer(file_parts, doc)
|
|
145
143
|
format_description(file_parts, doc)
|
|
146
144
|
format_tokens(file_parts, doc)
|
|
@@ -3,7 +3,6 @@ from typing import Optional
|
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
5
|
|
|
6
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
7
6
|
from tinybird.tb.modules.datafile.common import (
|
|
8
7
|
Datafile,
|
|
9
8
|
DatafileSyntaxError,
|
|
@@ -11,6 +10,7 @@ from tinybird.tb.modules.datafile.common import (
|
|
|
11
10
|
parse,
|
|
12
11
|
)
|
|
13
12
|
from tinybird.tb.modules.datafile.exceptions import ParseException
|
|
13
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def parse_datasource(
|
|
@@ -3,7 +3,6 @@ from typing import Optional
|
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
5
|
|
|
6
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
7
6
|
from tinybird.sql_template import get_template_and_variables, render_sql_template
|
|
8
7
|
from tinybird.tb.modules.datafile.common import (
|
|
9
8
|
Datafile,
|
|
@@ -12,6 +11,7 @@ from tinybird.tb.modules.datafile.common import (
|
|
|
12
11
|
parse,
|
|
13
12
|
)
|
|
14
13
|
from tinybird.tb.modules.datafile.exceptions import IncludeFileNotFoundException, ParseException
|
|
14
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
15
15
|
from tinybird.tornado_template import UnClosedIfError
|
|
16
16
|
|
|
17
17
|
|
|
@@ -7,10 +7,10 @@ import aiofiles
|
|
|
7
7
|
import click
|
|
8
8
|
|
|
9
9
|
from tinybird.client import AuthNoTokenException, TinyB
|
|
10
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
11
10
|
from tinybird.tb.modules.datafile.common import get_name_version
|
|
12
11
|
from tinybird.tb.modules.datafile.format_datasource import format_datasource
|
|
13
12
|
from tinybird.tb.modules.datafile.format_pipe import format_pipe
|
|
13
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
async def folder_pull(
|
|
@@ -20,7 +20,6 @@ from tinybird.tb.modules.config import CLIConfig
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
21
|
from tinybird.connectors import Connector
|
|
22
22
|
|
|
23
|
-
from tinybird.feedback_manager import FeedbackManager
|
|
24
23
|
from tinybird.tb.modules.cli import cli
|
|
25
24
|
from tinybird.tb.modules.common import (
|
|
26
25
|
_analyze,
|
|
@@ -42,6 +41,7 @@ from tinybird.tb.modules.common import (
|
|
|
42
41
|
)
|
|
43
42
|
from tinybird.tb.modules.datafile.common import get_name_version
|
|
44
43
|
from tinybird.tb.modules.exceptions import CLIDatasourceException
|
|
44
|
+
from tinybird.tb.modules.feedback_manager import FeedbackManager
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
@cli.group()
|
|
@@ -125,26 +125,6 @@ async def datasource_ls(ctx: Context, match: Optional[str], format_: str):
|
|
|
125
125
|
@datasource.command(name="append")
|
|
126
126
|
@click.argument("datasource_name")
|
|
127
127
|
@click.argument("url", nargs=-1)
|
|
128
|
-
@click.option(
|
|
129
|
-
"--connector",
|
|
130
|
-
type=click.Choice(["bigquery", "snowflake"], case_sensitive=True),
|
|
131
|
-
help="Import from one of the selected connectors",
|
|
132
|
-
hidden=True,
|
|
133
|
-
)
|
|
134
|
-
@click.option("--sql", default=None, help="Query to extract data from one of the SQL connectors", hidden=True)
|
|
135
|
-
@click.option(
|
|
136
|
-
"--incremental",
|
|
137
|
-
default=None,
|
|
138
|
-
help="It does an incremental append, taking the max value for the date column name provided as a parameter. It only works when the `connector` parameter is passed.",
|
|
139
|
-
hidden=True,
|
|
140
|
-
)
|
|
141
|
-
@click.option(
|
|
142
|
-
"--ignore-empty",
|
|
143
|
-
help="Wheter or not to ignore empty results from the connector",
|
|
144
|
-
is_flag=True,
|
|
145
|
-
default=False,
|
|
146
|
-
hidden=True,
|
|
147
|
-
)
|
|
148
128
|
@click.option("--concurrency", help="How many files to submit concurrently", default=1, hidden=True)
|
|
149
129
|
@click.pass_context
|
|
150
130
|
@coro
|
|
@@ -152,10 +132,6 @@ async def datasource_append(
|
|
|
152
132
|
ctx: Context,
|
|
153
133
|
datasource_name: str,
|
|
154
134
|
url,
|
|
155
|
-
connector: Optional[str],
|
|
156
|
-
sql: Optional[str],
|
|
157
|
-
incremental: Optional[str],
|
|
158
|
-
ignore_empty: bool,
|
|
159
135
|
concurrency: int,
|
|
160
136
|
):
|
|
161
137
|
"""
|
|
@@ -164,37 +140,14 @@ async def datasource_append(
|
|
|
164
140
|
- Load from URL `tb datasource append [datasource_name] https://url_to_csv`
|
|
165
141
|
|
|
166
142
|
- Load from local file `tb datasource append [datasource_name] /path/to/local/file`
|
|
167
|
-
|
|
168
|
-
- Load from connector `tb datasource append [datasource_name] --connector [connector_name] --sql [the_sql_to_extract_from]`
|
|
169
143
|
"""
|
|
170
144
|
|
|
171
|
-
if not url and not connector:
|
|
172
|
-
raise CLIDatasourceException(FeedbackManager.error_missing_url_or_connector(datasource=datasource_name))
|
|
173
|
-
|
|
174
|
-
if incremental and not connector:
|
|
175
|
-
raise CLIDatasourceException(FeedbackManager.error_incremental_not_supported())
|
|
176
|
-
|
|
177
145
|
client: TinyB = ctx.obj["client"]
|
|
178
|
-
if incremental:
|
|
179
|
-
date = None
|
|
180
|
-
source_column = incremental.split(":")[0]
|
|
181
|
-
dest_column = incremental.split(":")[-1]
|
|
182
|
-
result = await client.query(f"SELECT max({dest_column}) as inc from {datasource_name} FORMAT JSON")
|
|
183
|
-
try:
|
|
184
|
-
date = result["data"][0]["inc"]
|
|
185
|
-
except Exception as e:
|
|
186
|
-
raise CLIDatasourceException(f"{str(e)}")
|
|
187
|
-
if date:
|
|
188
|
-
sql = f"{sql} WHERE {source_column} > '{date}'"
|
|
189
146
|
await push_data(
|
|
190
|
-
ctx,
|
|
191
147
|
client,
|
|
192
148
|
datasource_name,
|
|
193
149
|
url,
|
|
194
|
-
connector,
|
|
195
|
-
sql,
|
|
196
150
|
mode="append",
|
|
197
|
-
ignore_empty=ignore_empty,
|
|
198
151
|
concurrency=concurrency,
|
|
199
152
|
)
|
|
200
153
|
|
|
@@ -202,33 +155,16 @@ async def datasource_append(
|
|
|
202
155
|
@datasource.command(name="replace")
|
|
203
156
|
@click.argument("datasource_name")
|
|
204
157
|
@click.argument("url", nargs=-1)
|
|
205
|
-
@click.option(
|
|
206
|
-
"--connector",
|
|
207
|
-
type=click.Choice(["bigquery", "snowflake"], case_sensitive=True),
|
|
208
|
-
help="Import from one of the selected connectors",
|
|
209
|
-
hidden=True,
|
|
210
|
-
)
|
|
211
|
-
@click.option("--sql", default=None, help="Query to extract data from one of the SQL connectors", hidden=True)
|
|
212
158
|
@click.option("--sql-condition", default=None, help="SQL WHERE condition to replace data", hidden=True)
|
|
213
159
|
@click.option("--skip-incompatible-partition-key", is_flag=True, default=False, hidden=True)
|
|
214
|
-
@click.option(
|
|
215
|
-
"--ignore-empty",
|
|
216
|
-
help="Wheter or not to ignore empty results from the connector",
|
|
217
|
-
is_flag=True,
|
|
218
|
-
default=False,
|
|
219
|
-
hidden=True,
|
|
220
|
-
)
|
|
221
160
|
@click.pass_context
|
|
222
161
|
@coro
|
|
223
162
|
async def datasource_replace(
|
|
224
|
-
ctx,
|
|
163
|
+
ctx: Context,
|
|
225
164
|
datasource_name,
|
|
226
165
|
url,
|
|
227
|
-
connector,
|
|
228
|
-
sql,
|
|
229
166
|
sql_condition,
|
|
230
167
|
skip_incompatible_partition_key,
|
|
231
|
-
ignore_empty: bool,
|
|
232
168
|
):
|
|
233
169
|
"""
|
|
234
170
|
Replaces the data in a data source from a URL, local file or a connector
|
|
@@ -236,26 +172,19 @@ async def datasource_replace(
|
|
|
236
172
|
- Replace from URL `tb datasource replace [datasource_name] https://url_to_csv --sql-condition "country='ES'"`
|
|
237
173
|
|
|
238
174
|
- Replace from local file `tb datasource replace [datasource_name] /path/to/local/file --sql-condition "country='ES'"`
|
|
239
|
-
|
|
240
|
-
- Replace from connector `tb datasource replace [datasource_name] --connector [connector_name] --sql [the_sql_to_extract_from] --sql-condition "country='ES'"`
|
|
241
175
|
"""
|
|
242
176
|
|
|
243
|
-
if not url and not connector:
|
|
244
|
-
raise CLIDatasourceException(FeedbackManager.error_missing_url_or_connector(datasource=datasource_name))
|
|
245
|
-
|
|
246
177
|
replace_options = set()
|
|
247
178
|
if skip_incompatible_partition_key:
|
|
248
179
|
replace_options.add("skip_incompatible_partition_key")
|
|
180
|
+
client: TinyB = ctx.obj["client"]
|
|
249
181
|
await push_data(
|
|
250
|
-
|
|
182
|
+
client,
|
|
251
183
|
datasource_name,
|
|
252
184
|
url,
|
|
253
|
-
connector,
|
|
254
|
-
sql,
|
|
255
185
|
mode="replace",
|
|
256
186
|
sql_condition=sql_condition,
|
|
257
187
|
replace_options=replace_options,
|
|
258
|
-
ignore_empty=ignore_empty,
|
|
259
188
|
)
|
|
260
189
|
|
|
261
190
|
|