tinybird 4.6.16.dev0__tar.gz → 4.6.18.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.16.dev0 → tinybird-4.6.18.dev0}/PKG-INFO +17 -1
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/ch_utils/engine.py +6 -1
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/config.py +0 -4
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/datafile/common.py +21 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/service_datasources.py +40 -16
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/sql_toolset.py +0 -5
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/__cli__.py +2 -2
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/client.py +2 -2
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/common.py +2 -2
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/deployment.py +5 -8
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/deployment_common.py +108 -15
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird.egg-info/PKG-INFO +17 -1
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/setup.cfg +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/__cli__.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/ch_utils/constants.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/check_pypi.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/client.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/context.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/datafile/exceptions.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/datafile/parse_connection.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/datafile/parse_datasource.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/datafile/parse_pipe.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/datatypes.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/feedback_manager.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/git_settings.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/iterating/__init__.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/iterating/data_branch_modes.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/prompts.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/sql.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/sql_template.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/sql_template_fmt.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/syncasync.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/check_pypi.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/cli.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/config.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/branch.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/build.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/build_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/cicd.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/cli.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/config.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/connection.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/connection_dynamodb.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/connection_kafka.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/connection_s3.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/copy.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/create.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/build.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/build_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/build_datasource.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/build_pipe.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/diff.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/fixture.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/format_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/format_connection.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/format_datasource.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/format_pipe.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/pipe_checker.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/playground.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/pull.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datasource.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/deprecations.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/endpoint.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/exceptions.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/feedback_manager.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/fmt.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/info.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/infra.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/job.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/job_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/llm.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/llm_utils.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/local.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/local_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/local_logs.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/login.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/login_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/logout.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/logs.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/materialization.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/open.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/pipe.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/preview.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/project.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/project_commands.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/py_project.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/query_output.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/regions.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/secret.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/secret_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/sink.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/table.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/telemetry.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/test.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/test_common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/token.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/ts_project.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/watch.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/workspace.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/workspace_members.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/auth.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/branch.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/cicd.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/cli.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/common.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/config.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/connection.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/datasource.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/exceptions.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/fmt.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/job.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/pipe.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/regions.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/tag.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/telemetry.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/test.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/tinyunit/tinyunit.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/workspace.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb_cli_modules/workspace_members.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tornado_template.py +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird.egg-info/SOURCES.txt +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird.egg-info/dependency_links.txt +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird.egg-info/entry_points.txt +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.dev0}/tinybird.egg-info/requires.txt +0 -0
- {tinybird-4.6.16.dev0 → tinybird-4.6.18.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.18.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -51,11 +51,27 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
51
51
|
|
|
52
52
|
Changelog
|
|
53
53
|
----------
|
|
54
|
+
|
|
55
|
+
4.6.16
|
|
56
|
+
********
|
|
57
|
+
|
|
58
|
+
- `Fixed` ``tb deployment promote --wait`` and ``tb deployment discard --wait`` no longer hang forever when the server reports the old/discarded deployment removal as ``failed``; the CLI now detects the failure, prints the deployment errors, and exits non-zero.
|
|
59
|
+
|
|
60
|
+
4.6.15
|
|
61
|
+
********
|
|
62
|
+
|
|
63
|
+
- `Fixed` ``tb deploy`` waits for the old deployment to delete to avoid clashing with a new deployment submission.
|
|
64
|
+
|
|
54
65
|
4.6.14
|
|
55
66
|
********
|
|
56
67
|
|
|
57
68
|
- `Changed` ``tb datasource append`` and ``tb datasource replace`` submit local CSV, NDJSON, and Parquet files through the v1 import endpoint by default. ``tb datasource append --events`` also submits its request body through v1. These asynchronous imports print the queued job ID; pass ``--wait`` to wait for completion. Remote URL imports continue to use their existing route.
|
|
58
69
|
|
|
70
|
+
4.6.14
|
|
71
|
+
********
|
|
72
|
+
|
|
73
|
+
- `Fixed` `tb migrate-to-forward` correctly finds and offers to delete all branches, not just those created by the user running the migration.
|
|
74
|
+
|
|
59
75
|
4.6.13
|
|
60
76
|
********
|
|
61
77
|
|
|
@@ -476,6 +476,9 @@ def engine_options(columns, options: List[EngineOption], args: Dict):
|
|
|
476
476
|
if option_value:
|
|
477
477
|
if o.sql.lower() == "settings":
|
|
478
478
|
engine_settings = f"{o.sql} {option_value}"
|
|
479
|
+
# Conditional TTLs fail if we wrap the value in parentheses
|
|
480
|
+
elif o.sql.lower() == "ttl":
|
|
481
|
+
options_values.append(f"{o.sql} {option_value}")
|
|
479
482
|
else:
|
|
480
483
|
options_values.append(f"{o.sql} ({option_value})")
|
|
481
484
|
|
|
@@ -536,7 +539,9 @@ def engine_full_from_dict(
|
|
|
536
539
|
>>> engine_full_from_dict('MergeTree', {'sorting_key': 'local_date, cod_store'}, schema=schema)
|
|
537
540
|
'MergeTree() ORDER BY (local_date, cod_store)'
|
|
538
541
|
>>> engine_full_from_dict('MergeTree', {'partition_key': 'toDate(timestamp)', 'sorting_key': 'local_date, cod_store', 'settings': 'index_granularity = 32, index_granularity_bytes = 2048', 'ttl': 'toDate(local_date) + INTERVAL 1 DAY'}, schema=schema)
|
|
539
|
-
'MergeTree() PARTITION BY (toDate(timestamp)) ORDER BY (local_date, cod_store) TTL
|
|
542
|
+
'MergeTree() PARTITION BY (toDate(timestamp)) ORDER BY (local_date, cod_store) TTL toDate(local_date) + INTERVAL 1 DAY SETTINGS index_granularity = 32, index_granularity_bytes = 2048'
|
|
543
|
+
>>> engine_full_from_dict('MergeTree', {'sorting_key': 'timestamp', 'ttl': 'timestamp + INTERVAL 1 DAY DELETE WHERE is_deleted = 1'}, schema=schema)
|
|
544
|
+
'MergeTree() ORDER BY (timestamp) TTL timestamp + INTERVAL 1 DAY DELETE WHERE is_deleted = 1'
|
|
540
545
|
|
|
541
546
|
>>> schema = ''
|
|
542
547
|
>>> engine_full_from_dict('CollapsingMergeTree', {'sign': 'sign_column'}, schema=schema)
|
|
@@ -49,11 +49,7 @@ LEGACY_HOSTS = {
|
|
|
49
49
|
"https://ui.europe-west2.gcp.tinybird.co": "https://cloud.tinybird.co/gcp/europe-west2",
|
|
50
50
|
"https://ui.ap-east.aws.tinybird.co": "https://app.tinybird.co/aws/ap-east-1",
|
|
51
51
|
"https://ui.ap-east-1.aws.tinybird.co": "https://app.tinybird.co/aws/ap-east-1",
|
|
52
|
-
"https://ui.split.tinybird.co": "https://app.tinybird.co/aws/split-us-east",
|
|
53
|
-
"https://ui.split.us-west-2.aws.tinybird.co": "https://app.tinybird.co/aws/split-us-west-2",
|
|
54
52
|
"https://ui.northamerica-northeast2.gcp.tinybird.co": "https://app.tinybird.co/gcp/northamerica-northeast2",
|
|
55
|
-
"https://api.split.tinybird.co": "https://app.tinybird.co/aws/split-us-east",
|
|
56
|
-
"https://api.split.us-west-2.aws.tinybird.co": "https://app.tinybird.co/aws/split-us-west-2",
|
|
57
53
|
"https://ui.wadus1.gcp.tinybird.co": "https://app.wadus.tinybird.co/gcp/wadus1",
|
|
58
54
|
"https://ui.wadus2.gcp.tinybird.co": "https://app.wadus.tinybird.co/gcp/wadus2",
|
|
59
55
|
"https://ui.wadus3.gcp.tinybird.co": "https://app.wadus.tinybird.co/gcp/wadus3",
|
|
@@ -278,6 +278,12 @@ REQUIRED_DYNAMODB_PARAMS = {
|
|
|
278
278
|
}
|
|
279
279
|
DYNAMODB_PARAMS = REQUIRED_DYNAMODB_PARAMS
|
|
280
280
|
|
|
281
|
+
REQUIRED_POSTGRES_PARAMS = {
|
|
282
|
+
"pg_connection_name",
|
|
283
|
+
"pg_table",
|
|
284
|
+
}
|
|
285
|
+
POSTGRES_PARAMS = REQUIRED_POSTGRES_PARAMS
|
|
286
|
+
|
|
281
287
|
|
|
282
288
|
def extract_column_names_from_sorting_key_part(part: str) -> List[str]:
|
|
283
289
|
"""
|
|
@@ -602,6 +608,13 @@ class Datafile:
|
|
|
602
608
|
raise DatafileValidationError(
|
|
603
609
|
f"Invalid import schedule '{node['import_schedule']}'. Only {sorted(VALID_BLOB_STORAGE_CRON_VALUES)} values are allowed"
|
|
604
610
|
)
|
|
611
|
+
# Validate Postgres params
|
|
612
|
+
if any(param in node for param in POSTGRES_PARAMS) and (
|
|
613
|
+
missing := [param for param in REQUIRED_POSTGRES_PARAMS if param not in node]
|
|
614
|
+
):
|
|
615
|
+
raise DatafileValidationError(
|
|
616
|
+
f"Some Postgres params have been provided, but the following required ones are missing: {missing}"
|
|
617
|
+
)
|
|
605
618
|
|
|
606
619
|
else:
|
|
607
620
|
# We cannot validate a datafile whose kind is unknown
|
|
@@ -2068,6 +2081,8 @@ def parse(
|
|
|
2068
2081
|
"import_query": assign_var("import_query"), # Deprecated, BQ and SFK
|
|
2069
2082
|
"import_table_arn": assign_var("import_table_arn"), # Only for DynamoDB
|
|
2070
2083
|
"import_export_bucket": assign_var("import_export_bucket"), # For DynamoDB
|
|
2084
|
+
"pg_connection_name": assign_var("pg_connection_name"),
|
|
2085
|
+
"pg_table": assign_var("pg_table"),
|
|
2071
2086
|
"shared_with": shared_with,
|
|
2072
2087
|
"export_service": export_service, # Deprecated
|
|
2073
2088
|
"forward_query": forward_query,
|
|
@@ -2128,6 +2143,12 @@ def parse(
|
|
|
2128
2143
|
"gcs_secret": assign_var("gcs_hmac_secret"),
|
|
2129
2144
|
"gcs_hmac_access_id": assign_var("gcs_hmac_access_id"),
|
|
2130
2145
|
"gcs_hmac_secret": assign_var("gcs_hmac_secret"),
|
|
2146
|
+
"pg_host": assign_var("pg_host"),
|
|
2147
|
+
"pg_port": assign_var("pg_port"),
|
|
2148
|
+
"pg_database": assign_var("pg_database"),
|
|
2149
|
+
"pg_user": assign_var("pg_user"),
|
|
2150
|
+
"pg_password": assign_var("pg_password"),
|
|
2151
|
+
"pg_ssl_mode": assign_var("pg_ssl_mode"),
|
|
2131
2152
|
"include": include,
|
|
2132
2153
|
},
|
|
2133
2154
|
}
|
|
@@ -48,6 +48,7 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
48
48
|
{"name": "client_ip", "type": "Nullable(String)"},
|
|
49
49
|
{"name": "resource_tags", "type": "Array(String)"},
|
|
50
50
|
{"name": "memory_usage", "type": "UInt64"},
|
|
51
|
+
{"name": "replica", "type": "String"},
|
|
51
52
|
],
|
|
52
53
|
},
|
|
53
54
|
{
|
|
@@ -333,6 +334,25 @@ def get_tinybird_service_datasources() -> List[Dict[str, Any]]:
|
|
|
333
334
|
{"name": "job_metadata", "type": "String"},
|
|
334
335
|
],
|
|
335
336
|
},
|
|
337
|
+
{
|
|
338
|
+
"name": "tinybird.rate_limits_log",
|
|
339
|
+
"description": "Endpoint concurrency limiter transitions in your workspace.",
|
|
340
|
+
"dateColumn": "timestamp",
|
|
341
|
+
"engine": {
|
|
342
|
+
"engine": "MergeTree",
|
|
343
|
+
"sorting_key": "timestamp, pipe_name",
|
|
344
|
+
"partition_key": "toYYYYMM(timestamp)",
|
|
345
|
+
},
|
|
346
|
+
"columns": [
|
|
347
|
+
{"name": "timestamp", "type": "DateTime64(3)"},
|
|
348
|
+
{"name": "workspace_id", "type": "String"},
|
|
349
|
+
{"name": "workspace_name", "type": "String"},
|
|
350
|
+
{"name": "pipe_name", "type": "String"},
|
|
351
|
+
{"name": "rate_limit_type", "type": "LowCardinality(String)"},
|
|
352
|
+
{"name": "action", "type": "LowCardinality(String)"},
|
|
353
|
+
{"name": "limit_metadata", "type": "String"},
|
|
354
|
+
],
|
|
355
|
+
},
|
|
336
356
|
{
|
|
337
357
|
"name": "tinybird.hook_log",
|
|
338
358
|
"description": "Log of hook executions and their results.",
|
|
@@ -518,22 +538,6 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
518
538
|
{"name": "origin", "type": "String"},
|
|
519
539
|
],
|
|
520
540
|
},
|
|
521
|
-
{
|
|
522
|
-
"name": "organization.processed_data",
|
|
523
|
-
"description": "Information related to all processed data per day per workspace.",
|
|
524
|
-
"dateColumn": "date",
|
|
525
|
-
"engine": {
|
|
526
|
-
"engine": "SummingMergeTree",
|
|
527
|
-
"sorting_key": "database, date",
|
|
528
|
-
"partition_key": "toYYYYMM(date)",
|
|
529
|
-
},
|
|
530
|
-
"columns": [
|
|
531
|
-
{"name": "date", "type": "Date"},
|
|
532
|
-
{"name": "database", "type": "String"},
|
|
533
|
-
{"name": "read_bytes", "type": "UInt64"},
|
|
534
|
-
{"name": "written_bytes", "type": "UInt64"},
|
|
535
|
-
],
|
|
536
|
-
},
|
|
537
541
|
{
|
|
538
542
|
"name": "organization.datasources_storage",
|
|
539
543
|
"description": "Similar to tinybird.datasources_storage but with data for all Organization Workspaces.",
|
|
@@ -683,6 +687,7 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
683
687
|
{"name": "user_agent", "type": "Nullable(String)"},
|
|
684
688
|
{"name": "resource_tags", "type": "Array(String)"},
|
|
685
689
|
{"name": "memory_usage", "type": "UInt64"},
|
|
690
|
+
{"name": "replica", "type": "String"},
|
|
686
691
|
],
|
|
687
692
|
},
|
|
688
693
|
{
|
|
@@ -726,6 +731,25 @@ def get_organization_service_datasources() -> List[Dict[str, Any]]:
|
|
|
726
731
|
{"name": "job_metadata", "type": "String"},
|
|
727
732
|
],
|
|
728
733
|
},
|
|
734
|
+
{
|
|
735
|
+
"name": "organization.rate_limits_log",
|
|
736
|
+
"description": "Endpoint concurrency limiter transitions across the organization.",
|
|
737
|
+
"dateColumn": "timestamp",
|
|
738
|
+
"engine": {
|
|
739
|
+
"engine": "MergeTree",
|
|
740
|
+
"sorting_key": "workspace_id, timestamp, pipe_name",
|
|
741
|
+
"partition_key": "toYYYYMM(timestamp)",
|
|
742
|
+
},
|
|
743
|
+
"columns": [
|
|
744
|
+
{"name": "timestamp", "type": "DateTime64(3)"},
|
|
745
|
+
{"name": "workspace_id", "type": "String"},
|
|
746
|
+
{"name": "workspace_name", "type": "String"},
|
|
747
|
+
{"name": "pipe_name", "type": "String"},
|
|
748
|
+
{"name": "rate_limit_type", "type": "LowCardinality(String)"},
|
|
749
|
+
{"name": "action", "type": "LowCardinality(String)"},
|
|
750
|
+
{"name": "limit_metadata", "type": "String"},
|
|
751
|
+
],
|
|
752
|
+
},
|
|
729
753
|
{
|
|
730
754
|
"name": "organization.sinks_ops_log",
|
|
731
755
|
"description": "Historic Logs for all Sink job executions across the organization",
|
|
@@ -493,7 +493,6 @@ def replace_tables_chquery_cached(
|
|
|
493
493
|
sorted_replacements: Optional[tuple] = None,
|
|
494
494
|
default_database: str = "",
|
|
495
495
|
output_one_line: bool = False,
|
|
496
|
-
timestamp: Optional[datetime] = None,
|
|
497
496
|
function_allow_list: Optional[FrozenSet[str]] = None,
|
|
498
497
|
settings_allow_list: Optional[FrozenSet[str]] = None,
|
|
499
498
|
) -> str:
|
|
@@ -536,7 +535,6 @@ def replace_tables(
|
|
|
536
535
|
sql,
|
|
537
536
|
None,
|
|
538
537
|
output_one_line=output_one_line,
|
|
539
|
-
timestamp=timestamp,
|
|
540
538
|
function_allow_list=hashable_list,
|
|
541
539
|
settings_allow_list=hashable_settings_list,
|
|
542
540
|
)
|
|
@@ -610,7 +608,6 @@ def replace_tables(
|
|
|
610
608
|
sql,
|
|
611
609
|
None,
|
|
612
610
|
output_one_line=output_one_line,
|
|
613
|
-
timestamp=timestamp,
|
|
614
611
|
function_allow_list=hashable_list,
|
|
615
612
|
settings_allow_list=hashable_settings_list,
|
|
616
613
|
)
|
|
@@ -649,7 +646,6 @@ def replace_tables(
|
|
|
649
646
|
r,
|
|
650
647
|
default_database=default_database,
|
|
651
648
|
output_one_line=output_one_line,
|
|
652
|
-
timestamp=timestamp,
|
|
653
649
|
function_allow_list=hashable_list,
|
|
654
650
|
settings_allow_list=hashable_settings_list,
|
|
655
651
|
)
|
|
@@ -658,7 +654,6 @@ def replace_tables(
|
|
|
658
654
|
sql,
|
|
659
655
|
None,
|
|
660
656
|
output_one_line=output_one_line,
|
|
661
|
-
timestamp=timestamp,
|
|
662
657
|
function_allow_list=hashable_list,
|
|
663
658
|
settings_allow_list=hashable_settings_list,
|
|
664
659
|
)
|
|
@@ -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.18.dev0'
|
|
8
|
+
__revision__ = '0bbef5c'
|
|
@@ -833,8 +833,8 @@ class TinyB:
|
|
|
833
833
|
def user_workspace_branches(self, version: str = "v0"):
|
|
834
834
|
return self._req(f"/{version}/user/workspaces/?with_environments=true&only_environments=true")
|
|
835
835
|
|
|
836
|
-
def branches(self):
|
|
837
|
-
return self._req("/
|
|
836
|
+
def branches(self, version: str = "v1"):
|
|
837
|
+
return self._req(f"/{version}/environments")
|
|
838
838
|
|
|
839
839
|
def releases(self, workspace_id):
|
|
840
840
|
return self._req(f"/v0/workspaces/{workspace_id}/releases")
|
|
@@ -18,7 +18,7 @@ from copy import deepcopy
|
|
|
18
18
|
from enum import Enum
|
|
19
19
|
from os import getcwd, getenv
|
|
20
20
|
from pathlib import Path
|
|
21
|
-
from typing import Any, Callable, Dict, Iterable, List, Literal, Optional, Set, Tuple, TypedDict, Union
|
|
21
|
+
from typing import Any, Callable, Dict, Iterable, List, Literal, NoReturn, Optional, Set, Tuple, TypedDict, Union
|
|
22
22
|
from urllib.parse import urlparse
|
|
23
23
|
|
|
24
24
|
import click
|
|
@@ -2370,7 +2370,7 @@ def ask_for_organization(
|
|
|
2370
2370
|
event_error_separator = "__error__"
|
|
2371
2371
|
|
|
2372
2372
|
|
|
2373
|
-
def sys_exit(event: str, msg: str) ->
|
|
2373
|
+
def sys_exit(event: str, msg: str) -> NoReturn:
|
|
2374
2374
|
sys.exit(f"{event}{event_error_separator}{msg}")
|
|
2375
2375
|
|
|
2376
2376
|
|
|
@@ -155,16 +155,13 @@ def api_fetch(url: str, headers: dict, request_from: Optional[str] = None) -> di
|
|
|
155
155
|
return {}
|
|
156
156
|
|
|
157
157
|
|
|
158
|
-
def _get_classic_workspace_branches(client: TinyB
|
|
159
|
-
|
|
160
|
-
return [branch for branch in branches if str(branch.get("main")) == workspace_id]
|
|
158
|
+
def _get_classic_workspace_branches(client: TinyB) -> list[dict[str, Any]]:
|
|
159
|
+
return client.branches(version="v0").get("environments", [])
|
|
161
160
|
|
|
162
161
|
|
|
163
|
-
def _cleanup_classic_migration_blockers(client: TinyB
|
|
164
|
-
workspace_id = str(config["id"])
|
|
165
|
-
|
|
162
|
+
def _cleanup_classic_migration_blockers(client: TinyB) -> None:
|
|
166
163
|
try:
|
|
167
|
-
branches = _get_classic_workspace_branches(client
|
|
164
|
+
branches = _get_classic_workspace_branches(client)
|
|
168
165
|
if not branches:
|
|
169
166
|
return
|
|
170
167
|
|
|
@@ -488,7 +485,7 @@ def migrate_to_forward(ctx: click.Context, allow_destructive_operations: bool) -
|
|
|
488
485
|
click.echo(FeedbackManager.info(message="Migration cancelled."))
|
|
489
486
|
return
|
|
490
487
|
|
|
491
|
-
_cleanup_classic_migration_blockers(client
|
|
488
|
+
_cleanup_classic_migration_blockers(client)
|
|
492
489
|
_persist_migrate_to_forward_config(project)
|
|
493
490
|
migrate_to_forward_workspace(client=client, output=output, dry_run=False)
|
|
494
491
|
create_deployment(
|
|
@@ -118,23 +118,57 @@ def _get_migrate_to_forward_error_message(result: dict[str, Any]) -> str:
|
|
|
118
118
|
def _is_first_deployment_with_seed_live(host: Optional[str], headers: dict) -> bool:
|
|
119
119
|
"""Best-effort check for first real deployment when seed deployment (id=0) is still live."""
|
|
120
120
|
try:
|
|
121
|
-
|
|
122
|
-
if response.status_code >= 300:
|
|
123
|
-
return False
|
|
124
|
-
|
|
125
|
-
result = response.json()
|
|
126
|
-
logging.debug(json.dumps(result, indent=2))
|
|
127
|
-
deployments = result.get("deployments") or []
|
|
128
|
-
if not deployments:
|
|
129
|
-
return False
|
|
130
|
-
|
|
131
|
-
live_deployment = next((deployment for deployment in deployments if deployment.get("live")), deployments[0])
|
|
132
|
-
return str(live_deployment.get("id")) == "0"
|
|
121
|
+
return _get_current_live_deployment_id(host, headers) == "0"
|
|
133
122
|
except Exception:
|
|
134
|
-
|
|
123
|
+
logging.exception("Error checking for live seed deployment while deciding first-deployment hint")
|
|
135
124
|
return False
|
|
136
125
|
|
|
137
126
|
|
|
127
|
+
def _list_deployments(host: Optional[str], headers: dict) -> list[dict]:
|
|
128
|
+
"""Fetch the current deployments. Raises if the lookup fails."""
|
|
129
|
+
response = requests.get(f"{host}/v1/deployments", headers=headers)
|
|
130
|
+
response.raise_for_status()
|
|
131
|
+
|
|
132
|
+
result = response.json()
|
|
133
|
+
logging.debug(json.dumps(result, indent=2))
|
|
134
|
+
return result.get("deployments") or []
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def _get_current_live_deployment_id(host: Optional[str], headers: dict) -> Optional[str]:
|
|
138
|
+
deployments = _list_deployments(host, headers)
|
|
139
|
+
if not deployments:
|
|
140
|
+
return None
|
|
141
|
+
|
|
142
|
+
live_deployment = next((deployment for deployment in deployments if deployment.get("live")), deployments[0])
|
|
143
|
+
live_id = live_deployment.get("id")
|
|
144
|
+
return str(live_id) if live_id is not None else None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _get_lingering_old_deployment_id(host: Optional[str], headers: dict, new_deployment_id: str) -> Optional[str]:
|
|
148
|
+
"""Look up a still-active deployment other than `new_deployment_id`, if any."""
|
|
149
|
+
deployments = _list_deployments(host, headers)
|
|
150
|
+
other_deployment = next((d for d in deployments if str(d.get("id")) != new_deployment_id), None)
|
|
151
|
+
return str(other_deployment["id"]) if other_deployment else None
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _wait_for_deployment_deletion(
|
|
155
|
+
host: Optional[str],
|
|
156
|
+
headers: dict,
|
|
157
|
+
deployment_id: str,
|
|
158
|
+
request_from: Optional[str] = None,
|
|
159
|
+
poll_interval: int = 5,
|
|
160
|
+
) -> bool: # whether the deployment has been deleted successfully
|
|
161
|
+
url = f"{host}/v1/deployments/{deployment_id}"
|
|
162
|
+
while True:
|
|
163
|
+
result = api_fetch(url, headers, request_from=request_from)
|
|
164
|
+
old_deployment = result.get("deployment")
|
|
165
|
+
if not old_deployment or old_deployment.get("status") == "deleted":
|
|
166
|
+
return True
|
|
167
|
+
if old_deployment.get("status") == "failed":
|
|
168
|
+
return False
|
|
169
|
+
time.sleep(poll_interval)
|
|
170
|
+
|
|
171
|
+
|
|
138
172
|
def _get_deployment_job(client: TinyB, deployment_id: Optional[Union[str, int]]) -> Optional[Dict[str, Any]]:
|
|
139
173
|
if deployment_id is None:
|
|
140
174
|
return None
|
|
@@ -264,12 +298,21 @@ def promote_deployment(
|
|
|
264
298
|
click.echo(FeedbackManager.error(message="Error parsing deployment from response"))
|
|
265
299
|
sys_exit("deployment_error", "Error parsing deployment from response")
|
|
266
300
|
|
|
267
|
-
|
|
301
|
+
last_deployment_status = last_deployment.get("status")
|
|
302
|
+
|
|
303
|
+
if last_deployment_status == "deleted":
|
|
268
304
|
if not is_first_deployment:
|
|
269
305
|
click.echo(FeedbackManager.info(message="✓ Old deployment removed"))
|
|
270
306
|
click.echo(FeedbackManager.success(message=f"✓ Deployment #{candidate_deployment.get('id')} is live!"))
|
|
271
307
|
break
|
|
272
308
|
|
|
309
|
+
if last_deployment_status == "failed":
|
|
310
|
+
click.echo(FeedbackManager.error(message="Removing the old deployment failed"))
|
|
311
|
+
deploy_errors = last_deployment.get("errors", [])
|
|
312
|
+
for deploy_error in deploy_errors:
|
|
313
|
+
click.echo(FeedbackManager.error(message=f"* {deploy_error}"))
|
|
314
|
+
sys_exit("deployment_error", "Removing the old deployment failed: " + str(deploy_errors))
|
|
315
|
+
|
|
273
316
|
time.sleep(5)
|
|
274
317
|
if is_first_deployment and ingest_hint and len(candidate_deployment.get("new_data_connector_ids", [])) == 0:
|
|
275
318
|
# This is the first deployment, so we prompt the user to ingest data
|
|
@@ -326,9 +369,23 @@ def discard_deployment(host: Optional[str], headers: dict, wait: bool, request_f
|
|
|
326
369
|
result = api_fetch(TINYBIRD_API_URL, headers, request_from=request_from)
|
|
327
370
|
|
|
328
371
|
deployment_to_discard = result.get("deployment")
|
|
329
|
-
if
|
|
372
|
+
if not deployment_to_discard:
|
|
373
|
+
click.echo(FeedbackManager.error(message="Error parsing deployment from response"))
|
|
374
|
+
sys_exit("deployment_error", "Error parsing deployment from response")
|
|
375
|
+
|
|
376
|
+
discard_status = deployment_to_discard.get("status")
|
|
377
|
+
|
|
378
|
+
if discard_status == "deleted":
|
|
330
379
|
click.echo(FeedbackManager.success(message="Discard process successfully completed"))
|
|
331
380
|
break
|
|
381
|
+
|
|
382
|
+
if discard_status == "failed":
|
|
383
|
+
click.echo(FeedbackManager.error(message="Discarding the deployment failed"))
|
|
384
|
+
deploy_errors = deployment_to_discard.get("errors", [])
|
|
385
|
+
for deploy_error in deploy_errors:
|
|
386
|
+
click.echo(FeedbackManager.error(message=f"* {deploy_error}"))
|
|
387
|
+
sys_exit("deployment_error", "Discarding the deployment failed: " + str(deploy_errors))
|
|
388
|
+
|
|
332
389
|
time.sleep(5)
|
|
333
390
|
|
|
334
391
|
|
|
@@ -635,6 +692,42 @@ def create_deployment(
|
|
|
635
692
|
click.echo(FeedbackManager.highlight(message="» Waiting for deployment to be promoted..."))
|
|
636
693
|
click.echo(FeedbackManager.info(message="✓ Deployment promoted"))
|
|
637
694
|
click.echo(FeedbackManager.success(message=f"✓ Deployment #{deployment.get('id')} is live!"))
|
|
695
|
+
|
|
696
|
+
old_deployment_id: Optional[str] = None
|
|
697
|
+
try:
|
|
698
|
+
old_deployment_id = _get_lingering_old_deployment_id(client.host, HEADERS, str(deployment.get("id")))
|
|
699
|
+
except Exception:
|
|
700
|
+
click.echo(
|
|
701
|
+
FeedbackManager.warning(
|
|
702
|
+
message="Could not confirm if there's a previous deployment to remove. "
|
|
703
|
+
f"If a follow-up `tb deploy` reports one already in progress, check `tb --{env} deployment ls`."
|
|
704
|
+
)
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
if old_deployment_id:
|
|
708
|
+
click.echo(FeedbackManager.highlight(message="» Removing old deployment..."))
|
|
709
|
+
try:
|
|
710
|
+
deleted = _wait_for_deployment_deletion(
|
|
711
|
+
client.host, HEADERS, old_deployment_id, request_from=request_from
|
|
712
|
+
)
|
|
713
|
+
except KeyboardInterrupt:
|
|
714
|
+
click.echo(
|
|
715
|
+
FeedbackManager.warning(
|
|
716
|
+
message=f"\nDeployment is live, but the old deployment is still being removed. "
|
|
717
|
+
f"Check its status with `tb --{env} deployment ls`."
|
|
718
|
+
)
|
|
719
|
+
)
|
|
720
|
+
raise click.Abort()
|
|
721
|
+
if deleted:
|
|
722
|
+
click.echo(FeedbackManager.info(message="✓ Old deployment removed"))
|
|
723
|
+
else:
|
|
724
|
+
click.echo(
|
|
725
|
+
FeedbackManager.warning(
|
|
726
|
+
message="Deployment is live, but the old deployment failed to be removed. "
|
|
727
|
+
f"Check its status with `tb --{env} deployment ls`."
|
|
728
|
+
)
|
|
729
|
+
)
|
|
730
|
+
|
|
638
731
|
if ingest_hint and len(deployment.get("new_data_connector_ids", [])) == 0 and is_first_deployment:
|
|
639
732
|
click.echo(
|
|
640
733
|
FeedbackManager.info(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: tinybird
|
|
3
|
-
Version: 4.6.
|
|
3
|
+
Version: 4.6.18.dev0
|
|
4
4
|
Summary: Tinybird Command Line Tool
|
|
5
5
|
Home-page: https://www.tinybird.co/docs/forward/commands
|
|
6
6
|
Author: Tinybird
|
|
@@ -51,11 +51,27 @@ The Tinybird command-line tool allows you to use all the Tinybird functionality
|
|
|
51
51
|
|
|
52
52
|
Changelog
|
|
53
53
|
----------
|
|
54
|
+
|
|
55
|
+
4.6.16
|
|
56
|
+
********
|
|
57
|
+
|
|
58
|
+
- `Fixed` ``tb deployment promote --wait`` and ``tb deployment discard --wait`` no longer hang forever when the server reports the old/discarded deployment removal as ``failed``; the CLI now detects the failure, prints the deployment errors, and exits non-zero.
|
|
59
|
+
|
|
60
|
+
4.6.15
|
|
61
|
+
********
|
|
62
|
+
|
|
63
|
+
- `Fixed` ``tb deploy`` waits for the old deployment to delete to avoid clashing with a new deployment submission.
|
|
64
|
+
|
|
54
65
|
4.6.14
|
|
55
66
|
********
|
|
56
67
|
|
|
57
68
|
- `Changed` ``tb datasource append`` and ``tb datasource replace`` submit local CSV, NDJSON, and Parquet files through the v1 import endpoint by default. ``tb datasource append --events`` also submits its request body through v1. These asynchronous imports print the queued job ID; pass ``--wait`` to wait for completion. Remote URL imports continue to use their existing route.
|
|
58
69
|
|
|
70
|
+
4.6.14
|
|
71
|
+
********
|
|
72
|
+
|
|
73
|
+
- `Fixed` `tb migrate-to-forward` correctly finds and offers to delete all branches, not just those created by the user running the migration.
|
|
74
|
+
|
|
59
75
|
4.6.13
|
|
60
76
|
********
|
|
61
77
|
|
|
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.16.dev0 → tinybird-4.6.18.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.16.dev0 → tinybird-4.6.18.dev0}/tinybird/tb/modules/datafile/format_connection.py
RENAMED
|
File without changes
|
{tinybird-4.6.16.dev0 → tinybird-4.6.18.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
|