tinybird 4.6.12.dev0__tar.gz → 4.6.13.dev0__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-4.6.12.dev0 → tinybird-4.6.13.dev0}/PKG-INFO +8 -1
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/datafile/common.py +19 -10
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/sql_template.py +39 -2
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/sql_toolset.py +25 -6
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/__cli__.py +2 -2
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird.egg-info/PKG-INFO +8 -1
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/setup.cfg +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/__cli__.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/ch_utils/engine.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/check_pypi.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/client.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/config.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/context.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/datatypes.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/feedback_manager.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/git_settings.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/iterating/__init__.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/iterating/data_branch_modes.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/prompts.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/service_datasources.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/sql.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/syncasync.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/cli.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/client.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/config.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/branch.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/build.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/build_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/cli.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/config.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/connection.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/connection_dynamodb.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/connection_kafka.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/connection_s3.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/create.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/format_connection.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/playground.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datasource.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/deployment.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/deployment_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/info.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/job.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/job_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/local.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/local_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/local_logs.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/login.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/logs.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/open.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/preview.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/project.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/project_commands.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/py_project.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/query_output.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/table.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/test.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/test_common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/token.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/ts_project.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tornado_template.py +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tinybird
|
|
3
|
-
Version: 4.6.
|
|
3
|
+
Version: 4.6.13.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -52,6 +52,13 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
52
52
|
Changelog
|
|
53
53
|
----------
|
|
54
54
|
|
|
55
|
+
4.6.12
|
|
56
|
+
********
|
|
57
|
+
|
|
58
|
+
- `Added` Forward sink pipes support ``{{ tb_secret(...) }}`` in ``EXPORT_*`` metadata (for example ``EXPORT_BUCKET_URI``). Secrets are resolved at deploy time and baked into the sink settings; changing a secret requires a redeploy.
|
|
59
|
+
- `Fixed` Forward deploy now raises an error when a secret used in sink metadata resolves to an empty value.
|
|
60
|
+
- `Fixed` Forward deploy now rejects ``{{ tb_secret(...) }}`` in ``EXPORT_SCHEDULE`` and ``COPY_SCHEDULE``. Use a literal cron expression (for example ``0 * * * *``) or ``@on-demand``.
|
|
61
|
+
|
|
55
62
|
4.6.11
|
|
56
63
|
********
|
|
57
64
|
|
|
@@ -401,12 +401,15 @@ class Datafile:
|
|
|
401
401
|
if node.get("mode") and node["mode"] not in ["append", "replace"]:
|
|
402
402
|
raise DatafileValidationError("COPY node mode must be append or replace")
|
|
403
403
|
# copy schedule must be @on-demand or a cron-expression
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
and
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
404
|
+
copy_schedule = node.get("copy_schedule")
|
|
405
|
+
if copy_schedule and copy_schedule != ON_DEMAND:
|
|
406
|
+
if isinstance(copy_schedule, str) and "tb_secret" in copy_schedule:
|
|
407
|
+
raise DatafileValidationError(
|
|
408
|
+
"COPY_SCHEDULE does not support { tb_secret(...) }. "
|
|
409
|
+
'Use a literal cron expression (for example "0 * * * *") or @on-demand.'
|
|
410
|
+
)
|
|
411
|
+
if not croniter.is_valid(copy_schedule):
|
|
412
|
+
raise DatafileValidationError("COPY node schedule must be @on-demand or a valid cron expression.")
|
|
410
413
|
for key in node.keys():
|
|
411
414
|
if key not in CopyParameters.valid_params():
|
|
412
415
|
raise DatafileValidationError(
|
|
@@ -503,10 +506,16 @@ class Datafile:
|
|
|
503
506
|
|
|
504
507
|
# Validate schedule format (common for both Kafka and S3/GCS)
|
|
505
508
|
export_schedule = node.get("export_schedule")
|
|
506
|
-
if export_schedule and export_schedule != ON_DEMAND
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
509
|
+
if export_schedule and export_schedule != ON_DEMAND:
|
|
510
|
+
if isinstance(export_schedule, str) and "tb_secret" in export_schedule:
|
|
511
|
+
raise DatafileValidationError(
|
|
512
|
+
f"Sink node {repr(node['name'])}: EXPORT_SCHEDULE does not support {{ tb_secret(...) }}. "
|
|
513
|
+
'Use a literal cron expression (for example "0 * * * *") or @on-demand.'
|
|
514
|
+
)
|
|
515
|
+
if not croniter.is_valid(export_schedule):
|
|
516
|
+
raise DatafileValidationError(
|
|
517
|
+
f"Sink node {repr(node['name'])} has invalid export_schedule '{export_schedule}'. Must be @on-demand or a valid cron expression."
|
|
518
|
+
)
|
|
510
519
|
|
|
511
520
|
def validate(self):
|
|
512
521
|
if self.kind == DatafileKind.pipe:
|
|
@@ -2911,13 +2911,21 @@ def extract_variables_from_sql(sql: str, params: List[Dict[str, Any]]) -> Dict[s
|
|
|
2911
2911
|
return defaults
|
|
2912
2912
|
|
|
2913
2913
|
|
|
2914
|
-
def render_template_with_secrets(
|
|
2914
|
+
def render_template_with_secrets(
|
|
2915
|
+
name: str,
|
|
2916
|
+
content: str,
|
|
2917
|
+
secrets: Optional[Dict[str, str]] = None,
|
|
2918
|
+
empty_secret_raises: bool = False,
|
|
2919
|
+
) -> str:
|
|
2915
2920
|
"""Renders a template with secrets, allowing for default values.
|
|
2916
2921
|
|
|
2917
2922
|
Args:
|
|
2918
2923
|
name: The name of the template
|
|
2919
2924
|
content: The template content
|
|
2920
2925
|
secrets: A dictionary mapping secret names to their values
|
|
2926
|
+
empty_secret_raises: When True, empty secret values or empty defaults raise
|
|
2927
|
+
instead of returning '""'. Used for sink metadata (Forward deploy) where
|
|
2928
|
+
an empty bucket path must not be baked as s3://"".
|
|
2921
2929
|
|
|
2922
2930
|
Returns:
|
|
2923
2931
|
The rendered template
|
|
@@ -2959,6 +2967,26 @@ def render_template_with_secrets(name: str, content: str, secrets: Optional[Dict
|
|
|
2959
2967
|
Traceback (most recent call last):
|
|
2960
2968
|
...
|
|
2961
2969
|
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Cannot access secret 'MISSING_SECRET'. Check the secret exists in the Workspace and the token has the required scope.
|
|
2970
|
+
|
|
2971
|
+
>>> render_template_with_secrets(
|
|
2972
|
+
... "sink_bucket",
|
|
2973
|
+
... "s3://{{ tb_secret('MISSING_SECRET', '') }}",
|
|
2974
|
+
... secrets = {},
|
|
2975
|
+
... empty_secret_raises=True,
|
|
2976
|
+
... )
|
|
2977
|
+
Traceback (most recent call last):
|
|
2978
|
+
...
|
|
2979
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Secret 'MISSING_SECRET' resolves to an empty value and cannot be used in sink metadata.
|
|
2980
|
+
|
|
2981
|
+
>>> render_template_with_secrets(
|
|
2982
|
+
... "sink_bucket",
|
|
2983
|
+
... "s3://{{ tb_secret('EMPTY_SECRET', 'fallback') }}",
|
|
2984
|
+
... secrets = {'EMPTY_SECRET': ''},
|
|
2985
|
+
... empty_secret_raises=True,
|
|
2986
|
+
... )
|
|
2987
|
+
Traceback (most recent call last):
|
|
2988
|
+
...
|
|
2989
|
+
tinybird.sql_template.SQLTemplateException: Template Syntax Error: Secret 'EMPTY_SECRET' resolves to an empty value and cannot be used in sink metadata.
|
|
2962
2990
|
"""
|
|
2963
2991
|
if not secrets:
|
|
2964
2992
|
secrets = {}
|
|
@@ -2974,15 +3002,24 @@ def render_template_with_secrets(name: str, content: str, secrets: Optional[Dict
|
|
|
2974
3002
|
The secret value or default
|
|
2975
3003
|
|
|
2976
3004
|
Raises:
|
|
2977
|
-
SQLTemplateException: If the secret is not found and no default is provided
|
|
3005
|
+
SQLTemplateException: If the secret is not found and no default is provided,
|
|
3006
|
+
or if empty_secret_raises is True and the resolved value is empty
|
|
2978
3007
|
"""
|
|
2979
3008
|
if secret_name in secrets:
|
|
2980
3009
|
value = secrets[secret_name]
|
|
2981
3010
|
if isinstance(value, str) and len(value) == 0:
|
|
3011
|
+
if empty_secret_raises:
|
|
3012
|
+
raise SQLTemplateException(
|
|
3013
|
+
f"Secret '{secret_name}' resolves to an empty value and cannot be used in sink metadata."
|
|
3014
|
+
)
|
|
2982
3015
|
return '""'
|
|
2983
3016
|
return value
|
|
2984
3017
|
elif default is not None:
|
|
2985
3018
|
if isinstance(default, str) and len(default) == 0:
|
|
3019
|
+
if empty_secret_raises:
|
|
3020
|
+
raise SQLTemplateException(
|
|
3021
|
+
f"Secret '{secret_name}' resolves to an empty value and cannot be used in sink metadata."
|
|
3022
|
+
)
|
|
2986
3023
|
return '""'
|
|
2987
3024
|
return default
|
|
2988
3025
|
else:
|
|
@@ -158,7 +158,20 @@ def has_unoptimized_join(sql: str, left_table: Optional[Union[Tuple[str, str], T
|
|
|
158
158
|
raise UnoptimizedJoinException(sql)
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
def
|
|
161
|
+
def _format_fragment_for_mutation_command(fragment: str) -> str:
|
|
162
|
+
"""Normalize a SQL fragment the way CH stores it in the
|
|
163
|
+
`system.mutations.command` column: format the expression with CH's own
|
|
164
|
+
formatter, then escape it as it appears inside the serialized command
|
|
165
|
+
(string literals keep backslash-escaped quotes)."""
|
|
166
|
+
formatted = chquery.format(f"""SELECT {fragment}""").split("SELECT ")[1]
|
|
167
|
+
formatted = formatted.replace("\\", "\\\\").replace("'", "''")
|
|
168
|
+
quoted = chquery.format(f"SELECT '{formatted}'").split("SELECT ")[1]
|
|
169
|
+
return quoted[1:-1]
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def format_where_for_mutation_command(
|
|
173
|
+
where_clause: str, lightweight: bool = False, partition: Optional[str] = None
|
|
174
|
+
) -> str:
|
|
162
175
|
"""
|
|
163
176
|
>>> format_where_for_mutation_command("numnights = 99")
|
|
164
177
|
'DELETE WHERE numnights = 99'
|
|
@@ -172,12 +185,18 @@ def format_where_for_mutation_command(where_clause: str, lightweight: bool = Fal
|
|
|
172
185
|
"DELETE WHERE reservationid = \\\\'\\\\\\\\\\\\'foo\\\\'"
|
|
173
186
|
>>> format_where_for_mutation_command("number < 3", lightweight=True)
|
|
174
187
|
'UPDATE _row_exists = 0 WHERE number < 3'
|
|
188
|
+
>>> format_where_for_mutation_command("number < 3", lightweight=True, partition="201901")
|
|
189
|
+
'UPDATE _row_exists = 0 IN PARTITION 201901 WHERE number < 3'
|
|
190
|
+
>>> format_where_for_mutation_command("number < 3", lightweight=True, partition="'2019-01-01'")
|
|
191
|
+
"UPDATE _row_exists = 0 IN PARTITION \\\\'2019-01-01\\\\' WHERE number < 3"
|
|
175
192
|
"""
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
193
|
+
quoted_condition = _format_fragment_for_mutation_command(where_clause)
|
|
194
|
+
prefix = "UPDATE _row_exists = 0" if lightweight else "DELETE"
|
|
195
|
+
# Partition-scoped mutations store the partition expression in the
|
|
196
|
+
# command (`… IN PARTITION <expr> WHERE <cond>`), normalized by the same
|
|
197
|
+
# CH formatter, so it must be part of the match.
|
|
198
|
+
partition_clause = f" IN PARTITION {_format_fragment_for_mutation_command(partition)}" if partition else ""
|
|
199
|
+
return f"{prefix}{partition_clause} WHERE {quoted_condition}"
|
|
181
200
|
|
|
182
201
|
|
|
183
202
|
# Functions that take table/dictionary names as string literal arguments.
|
|
@@ -4,5 +4,5 @@ __description__ = 'Tinybird Command Line Tool'
|
|
|
4
4
|
__url__ = 'https://www.tinybird.co/docs/forward/commands'
|
|
5
5
|
__author__ = 'Tinybird'
|
|
6
6
|
__author_email__ = 'support@tinybird.co'
|
|
7
|
-
__version__ = '4.6.
|
|
8
|
-
__revision__ = '
|
|
7
|
+
__version__ = '4.6.13.dev0'
|
|
8
|
+
__revision__ = '9f77ad2'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tinybird
|
|
3
|
-
Version: 4.6.
|
|
3
|
+
Version: 4.6.13.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -52,6 +52,13 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
52
52
|
Changelog
|
|
53
53
|
----------
|
|
54
54
|
|
|
55
|
+
4.6.12
|
|
56
|
+
********
|
|
57
|
+
|
|
58
|
+
- `Added` Forward sink pipes support ``{{ tb_secret(...) }}`` in ``EXPORT_*`` metadata (for example ``EXPORT_BUCKET_URI``). Secrets are resolved at deploy time and baked into the sink settings; changing a secret requires a redeploy.
|
|
59
|
+
- `Fixed` Forward deploy now raises an error when a secret used in sink metadata resolves to an empty value.
|
|
60
|
+
- `Fixed` Forward deploy now rejects ``{{ tb_secret(...) }}`` in ``EXPORT_SCHEDULE`` and ``COPY_SCHEDULE``. Use a literal cron expression (for example ``0 * * * *``) or ``@on-demand``.
|
|
61
|
+
|
|
55
62
|
4.6.11
|
|
56
63
|
********
|
|
57
64
|
|
|
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
|
|
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-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/build_datasource.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/format_connection.py
RENAMED
|
File without changes
|
{tinybird-4.6.12.dev0 → tinybird-4.6.13.dev0}/tinybird/tb/modules/datafile/format_datasource.py
RENAMED
|
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
|
|
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
|
|
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
|