mainsequence 4.1.3__tar.gz → 4.1.4__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.
- {mainsequence-4.1.3 → mainsequence-4.1.4}/PKG-INFO +1 -1
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/base.py +10 -31
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/data_sources_interfaces/duckdb.py +2 -83
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/data_sources_interfaces/sqlite.py +1 -70
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/models_metatables.py +8 -279
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/utils.py +0 -3
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/__init__.py +0 -2
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/data_nodes/__init__.py +0 -2
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/data_nodes/data_nodes.py +8 -29
- mainsequence-4.1.4/mainsequence/meta_tables/data_nodes/models.py +33 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/data_nodes/namespacing.py +2 -2
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/sqlalchemy_contracts.py +3 -3
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence.egg-info/PKG-INFO +1 -1
- {mainsequence-4.1.3 → mainsequence-4.1.4}/pyproject.toml +1 -1
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_build_operations_hashing.py +8 -9
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_data_node_storage_dimension_queries.py +2 -40
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_data_node_update_flow.py +13 -40
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_duckdb_interface_dimensions.py +0 -16
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_filter_normalization.py +10 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_meta_tables_sqlalchemy_contracts.py +1 -1
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_run_configuration.py +16 -6
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_sqlite_interface_dimensions.py +0 -16
- mainsequence-4.1.3/mainsequence/meta_tables/data_nodes/models.py +0 -106
- {mainsequence-4.1.3 → mainsequence-4.1.4}/LICENSE +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/README.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/AGENTS.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/a2a_communication/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/application_surfaces/api_surfaces/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/command_center/adapter_from_api/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/command_center/api_mock_prototyping/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/command_center/app_components/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/command_center/connections/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/command_center/workspace_analysis/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/command_center/workspace_builder/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/command_center/workspace_design/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/dashboards/streamlit/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/data_access/exploration/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/data_publishing/data_nodes/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/data_publishing/meta_tables/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/maintenance/bug_auditor/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/ms-markets/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/platform_operations/access_control_and_sharing/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/platform_operations/orchestration_and_releases/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/project_builder/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/agent_scaffold/skills/project_to_agent/SKILL.md +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/__init__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/__main__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/bootstrap.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/__init__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/api.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/browser_auth.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/cli.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/config.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/docker_utils.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/doctor.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/local_ops.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/model_filters.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/project_status.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/pydantic_cli.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/sdk_utils.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/ssh_utils.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/cli/ui.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/__init__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/agent_runtime_models.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/client.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/command_center/__init__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/command_center/app_component.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/command_center/connections.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/command_center/data_models.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/command_center/workspace.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/command_center/workspace_snapshot.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/data_sources_interfaces/__init__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/dtype_codec.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/exceptions.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/fastapi/__init__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/fastapi/auth.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/models_foundry.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/models_helpers.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/models_user.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/compute_validation.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/defaults.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/instrumentation/__init__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/instrumentation/utils.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/logconf.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/__main__.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/compiled_sql.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/config.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/configuration_models.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/data_nodes/build_operations.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/data_nodes/persist_managers.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/data_nodes/run_operations.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/data_nodes/utils.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/future_registry.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/hashing.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/pydantic_metadata.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/meta_tables/utils.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/runtime_flags.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence.egg-info/SOURCES.txt +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence.egg-info/dependency_links.txt +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence.egg-info/entry_points.txt +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence.egg-info/requires.txt +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence.egg-info/top_level.txt +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/setup.cfg +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_auth_precedence.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_cli.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_cli_browser_auth.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_client.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_command_center_app_component_models.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_command_center_data_models.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_command_center_models.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_data_access_mixin_dimension_audit.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_dependency_extras.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_logconf.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_meta_tables_client_models.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_models_user_request_bound_auth.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_pod_project_resolution.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_project_batch_jobs_from_file.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_secret_client_model.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_source_table_configuration.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_update_runner_uid_runtime.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_update_statistics.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_update_uid_guards.py +0 -0
- {mainsequence-4.1.3 → mainsequence-4.1.4}/tests/test_workspace_snapshot.py +0 -0
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import os
|
|
3
|
-
import warnings
|
|
4
3
|
from collections.abc import Callable, Iterable
|
|
5
4
|
from datetime import datetime
|
|
6
5
|
from typing import Any, ClassVar
|
|
@@ -98,13 +97,12 @@ class BaseObjectOrm:
|
|
|
98
97
|
"JobRun": "pods/job-run",
|
|
99
98
|
"Constant": "pods/constant",
|
|
100
99
|
"Secret": "pods/secret",
|
|
101
|
-
"ProjectBaseImage":"pods/project-base-image",
|
|
102
|
-
"ProjectImage":"pods/project-image",
|
|
100
|
+
"ProjectBaseImage": "pods/project-base-image",
|
|
101
|
+
"ProjectImage": "pods/project-image",
|
|
103
102
|
"GithubOrganization": "pods/github-organization",
|
|
104
|
-
"ProjectResource":"pods/project-resource",
|
|
105
|
-
"ResourceRelease":"pods/resource-release",
|
|
106
|
-
"Bucket":"pods/bucket",
|
|
107
|
-
|
|
103
|
+
"ProjectResource": "pods/project-resource",
|
|
104
|
+
"ResourceRelease": "pods/resource-release",
|
|
105
|
+
"Bucket": "pods/bucket",
|
|
108
106
|
}
|
|
109
107
|
ROOT_URL = API_ENDPOINT
|
|
110
108
|
LOADERS = loaders
|
|
@@ -527,7 +525,6 @@ class BaseObjectOrm:
|
|
|
527
525
|
)
|
|
528
526
|
raise_for_response(r)
|
|
529
527
|
|
|
530
|
-
|
|
531
528
|
data = r.json()
|
|
532
529
|
data["orm_class"] = cls.__name__
|
|
533
530
|
return cls(**data)
|
|
@@ -540,7 +537,6 @@ class BaseObjectOrm:
|
|
|
540
537
|
if len(candidates) > 1:
|
|
541
538
|
raise ApiError(f"Multiple objects returned for {cls.__name__} with filters={filters}")
|
|
542
539
|
|
|
543
|
-
|
|
544
540
|
return candidates[0]
|
|
545
541
|
|
|
546
542
|
@classmethod
|
|
@@ -556,8 +552,6 @@ class BaseObjectOrm:
|
|
|
556
552
|
|
|
557
553
|
@staticmethod
|
|
558
554
|
def serialize_for_json(kwargs):
|
|
559
|
-
|
|
560
|
-
|
|
561
555
|
return serialize_to_json(kwargs)
|
|
562
556
|
|
|
563
557
|
@classmethod
|
|
@@ -598,15 +592,6 @@ class BaseObjectOrm:
|
|
|
598
592
|
|
|
599
593
|
return cls(**r.json())
|
|
600
594
|
|
|
601
|
-
@classmethod
|
|
602
|
-
def _warn_internal_id_compatibility(cls, method_name: str, replacement_name: str) -> None:
|
|
603
|
-
warnings.warn(
|
|
604
|
-
f"{cls.__name__}.{method_name}() is an internal-only compatibility shim; "
|
|
605
|
-
f"use {cls.__name__}.{replacement_name}() with uid instead.",
|
|
606
|
-
DeprecationWarning,
|
|
607
|
-
stacklevel=3,
|
|
608
|
-
)
|
|
609
|
-
|
|
610
595
|
@classmethod
|
|
611
596
|
def _destroy_by_reference(cls, public_reference, *args, timeout=None, **kwargs):
|
|
612
597
|
base_url = cls.get_object_url()
|
|
@@ -632,11 +617,6 @@ class BaseObjectOrm:
|
|
|
632
617
|
if r.status_code != 204:
|
|
633
618
|
raise_for_response(r)
|
|
634
619
|
|
|
635
|
-
@classmethod
|
|
636
|
-
def _destroy_by_id_compat(cls, instance_id, *args, timeout=None, **kwargs):
|
|
637
|
-
cls._warn_internal_id_compatibility("_destroy_by_id_compat", "destroy_by_uid")
|
|
638
|
-
return cls._destroy_by_reference(instance_id, *args, timeout=timeout, **kwargs)
|
|
639
|
-
|
|
640
620
|
@classmethod
|
|
641
621
|
def destroy_by_uid(cls, uid: str, *args, timeout=None, **kwargs):
|
|
642
622
|
return cls._destroy_by_reference(uid, *args, timeout=timeout, **kwargs)
|
|
@@ -679,7 +659,11 @@ class BaseObjectOrm:
|
|
|
679
659
|
aliases.add(choice)
|
|
680
660
|
else:
|
|
681
661
|
path = getattr(validation_alias, "path", None)
|
|
682
|
-
if
|
|
662
|
+
if (
|
|
663
|
+
isinstance(path, (list, tuple))
|
|
664
|
+
and len(path) == 1
|
|
665
|
+
and isinstance(path[0], str)
|
|
666
|
+
):
|
|
683
667
|
aliases.add(path[0])
|
|
684
668
|
|
|
685
669
|
return aliases
|
|
@@ -734,11 +718,6 @@ class BaseObjectOrm:
|
|
|
734
718
|
# Otherwise return a new instance
|
|
735
719
|
return cls(**body)
|
|
736
720
|
|
|
737
|
-
@classmethod
|
|
738
|
-
def _patch_by_id_compat(cls, instance_id, *args, _into=None, **kwargs):
|
|
739
|
-
cls._warn_internal_id_compatibility("_patch_by_id_compat", "patch_by_uid")
|
|
740
|
-
return cls._patch_by_reference(instance_id, *args, _into=_into, **kwargs)
|
|
741
|
-
|
|
742
721
|
@classmethod
|
|
743
722
|
def patch_by_uid(cls, uid: str, *args, _into=None, **kwargs):
|
|
744
723
|
return cls._patch_by_reference(uid, *args, _into=_into, **kwargs)
|
{mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/data_sources_interfaces/duckdb.py
RENAMED
|
@@ -22,7 +22,7 @@ from ..dtype_codec import (
|
|
|
22
22
|
token_to_pandas_dtype,
|
|
23
23
|
token_to_pandas_series,
|
|
24
24
|
)
|
|
25
|
-
from ..utils import DataFrequency
|
|
25
|
+
from ..utils import DataFrequency
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def get_logger():
|
|
@@ -711,8 +711,6 @@ class DuckDBInterface:
|
|
|
711
711
|
dimension_filters: dict[str, list[Any]] | None = None,
|
|
712
712
|
index_coordinates: list[dict[str, Any]] | None = None,
|
|
713
713
|
dimension_range_map: list[dict[str, Any]] | None = None,
|
|
714
|
-
ids: list[str] | None = None,
|
|
715
|
-
unique_identifier_range_map: dict[str, dict[str, Any]] | None = None,
|
|
716
714
|
max_rows: int | None = None,
|
|
717
715
|
now: datetime.datetime | None = None,
|
|
718
716
|
) -> tuple[
|
|
@@ -971,45 +969,6 @@ class DuckDBInterface:
|
|
|
971
969
|
f"time_index_name {time_index_name!r} must be present in index_names {index_names!r}"
|
|
972
970
|
)
|
|
973
971
|
|
|
974
|
-
identity_dimensions = [name for name in index_names if name != time_index_name]
|
|
975
|
-
uses_legacy_unique_identifier = identity_dimensions == ["unique_identifier"]
|
|
976
|
-
|
|
977
|
-
if ids is not None and unique_identifier_range_map is not None:
|
|
978
|
-
raise ValueError("Cannot provide both 'ids' and 'unique_identifier_range_map'.")
|
|
979
|
-
if ids is not None and not uses_legacy_unique_identifier:
|
|
980
|
-
raise ValueError("Legacy 'ids' reads are valid only for unique_identifier tables.")
|
|
981
|
-
if unique_identifier_range_map is not None and not uses_legacy_unique_identifier:
|
|
982
|
-
raise ValueError(
|
|
983
|
-
"Legacy 'unique_identifier_range_map' reads are valid only for "
|
|
984
|
-
"unique_identifier tables."
|
|
985
|
-
)
|
|
986
|
-
if unique_identifier_range_map is not None and normalized_dimension_range_map is not None:
|
|
987
|
-
raise ValueError(
|
|
988
|
-
"Cannot provide both 'unique_identifier_range_map' and 'dimension_range_map'."
|
|
989
|
-
)
|
|
990
|
-
|
|
991
|
-
# If ids are given without a range map, create a simple one from start/end
|
|
992
|
-
if ids and (normalized_dimension_range_map is None):
|
|
993
|
-
normalized_dimension_range_map = [
|
|
994
|
-
{
|
|
995
|
-
"coordinate": {"unique_identifier": uid},
|
|
996
|
-
"start_date": start_ts.to_pydatetime() if start_ts is not None else None,
|
|
997
|
-
"start_date_operand": ">=",
|
|
998
|
-
"end_date": (
|
|
999
|
-
(end_ts or _to_utc_ts(now)).to_pydatetime()
|
|
1000
|
-
if (end_ts or now) is not None
|
|
1001
|
-
else None
|
|
1002
|
-
),
|
|
1003
|
-
"end_date_operand": "<=",
|
|
1004
|
-
}
|
|
1005
|
-
for uid in ids
|
|
1006
|
-
]
|
|
1007
|
-
if unique_identifier_range_map is not None:
|
|
1008
|
-
normalized_dimension_range_map = [
|
|
1009
|
-
{"coordinate": {"unique_identifier": uid}, **dict(info)}
|
|
1010
|
-
for uid, info in unique_identifier_range_map.items()
|
|
1011
|
-
]
|
|
1012
|
-
|
|
1013
972
|
# Compute global window from inputs
|
|
1014
973
|
if normalized_dimension_range_map:
|
|
1015
974
|
eff_start = _effective_start_from_range_map(normalized_dimension_range_map)
|
|
@@ -1192,10 +1151,7 @@ class DuckDBInterface:
|
|
|
1192
1151
|
dimension_filters: dict[str, list[Any]] | None = None,
|
|
1193
1152
|
index_coordinates: list[dict[str, Any]] | None = None,
|
|
1194
1153
|
dimension_range_map: list[dict[str, Any]] | None = None,
|
|
1195
|
-
ids: list[str] | None = None,
|
|
1196
1154
|
columns: list[str] | None = None,
|
|
1197
|
-
unique_identifier_range_map: UniqueIdentifierRangeMap | None = None,
|
|
1198
|
-
column_range_descriptor: dict[str, UniqueIdentifierRangeMap] | None = None,
|
|
1199
1155
|
) -> pd.DataFrame:
|
|
1200
1156
|
"""
|
|
1201
1157
|
Reads data from the specified table, with optional filtering.
|
|
@@ -1207,18 +1163,10 @@ class DuckDBInterface:
|
|
|
1207
1163
|
end (Optional[datetime.datetime]): Maximum temporal-column filter.
|
|
1208
1164
|
great_or_equal (bool): If True, use >= for start date comparison. Defaults to True.
|
|
1209
1165
|
less_or_equal (bool): If True, use <= for end date comparison. Defaults to True.
|
|
1210
|
-
ids (Optional[List[str]]): List of specific unique_identifiers to include.
|
|
1211
1166
|
columns (Optional[List[str]]): Specific columns to select. Reads all if None.
|
|
1212
|
-
unique_identifier_range_map (Optional[UniqueIdentifierRangeMap]):
|
|
1213
|
-
A map where keys are unique_identifiers and values are dicts specifying
|
|
1214
|
-
date ranges (start_date, end_date, start_date_operand, end_date_operand)
|
|
1215
|
-
for that identifier. Mutually exclusive with 'ids'.
|
|
1216
1167
|
|
|
1217
1168
|
Returns:
|
|
1218
1169
|
pd.DataFrame: The queried data, or an empty DataFrame if the table doesn't exist.
|
|
1219
|
-
|
|
1220
|
-
Raises:
|
|
1221
|
-
ValueError: If both `ids` and `unique_identifier_range_map` are provided.
|
|
1222
1170
|
"""
|
|
1223
1171
|
|
|
1224
1172
|
def qident(name: str) -> str:
|
|
@@ -1248,39 +1196,10 @@ class DuckDBInterface:
|
|
|
1248
1196
|
f"time_index_name {time_index_name!r} must be present in index_names {index_names!r}"
|
|
1249
1197
|
)
|
|
1250
1198
|
identity_dimensions = [name for name in index_names if name != time_index_name]
|
|
1251
|
-
uses_legacy_unique_identifier = identity_dimensions == ["unique_identifier"]
|
|
1252
|
-
|
|
1253
|
-
if ids is not None and unique_identifier_range_map is not None:
|
|
1254
|
-
raise ValueError("Cannot provide both 'ids' and 'unique_identifier_range_map'.")
|
|
1255
|
-
if ids is not None and not uses_legacy_unique_identifier:
|
|
1256
|
-
raise ValueError("Legacy 'ids' reads are valid only for unique_identifier tables.")
|
|
1257
|
-
if unique_identifier_range_map is not None and not uses_legacy_unique_identifier:
|
|
1258
|
-
raise ValueError(
|
|
1259
|
-
"Legacy 'unique_identifier_range_map' reads are valid only for "
|
|
1260
|
-
"unique_identifier tables."
|
|
1261
|
-
)
|
|
1262
|
-
if unique_identifier_range_map is not None and dimension_range_map is not None:
|
|
1263
|
-
raise ValueError(
|
|
1264
|
-
"Cannot provide both 'unique_identifier_range_map' and 'dimension_range_map'."
|
|
1265
|
-
)
|
|
1266
|
-
if column_range_descriptor is not None:
|
|
1267
|
-
raise NotImplementedError("DuckDB column_range_descriptor reads are not supported.")
|
|
1268
|
-
|
|
1269
|
-
if ids:
|
|
1270
|
-
dimension_filters = dict(dimension_filters or {})
|
|
1271
|
-
if "unique_identifier" in dimension_filters:
|
|
1272
|
-
raise ValueError("Cannot provide both 'ids' and a unique_identifier filter.")
|
|
1273
|
-
dimension_filters["unique_identifier"] = list(ids)
|
|
1274
|
-
|
|
1275
|
-
if unique_identifier_range_map is not None:
|
|
1276
|
-
dimension_range_map = [
|
|
1277
|
-
{"coordinate": {"unique_identifier": uid}, **dict(info)}
|
|
1278
|
-
for uid, info in unique_identifier_range_map.items()
|
|
1279
|
-
]
|
|
1280
1199
|
|
|
1281
1200
|
logger.debug(
|
|
1282
1201
|
f"Duck DB: Reading from table '{table}' with filters: start={start}, end={end}, "
|
|
1283
|
-
f"
|
|
1202
|
+
f"columns={columns}, range_map={dimension_range_map is not None}"
|
|
1284
1203
|
)
|
|
1285
1204
|
|
|
1286
1205
|
if not self.table_exists(table):
|
{mainsequence-4.1.3 → mainsequence-4.1.4}/mainsequence/client/data_sources_interfaces/sqlite.py
RENAMED
|
@@ -16,7 +16,6 @@ from ..dtype_codec import (
|
|
|
16
16
|
token_to_backend_type,
|
|
17
17
|
token_to_pandas_series,
|
|
18
18
|
)
|
|
19
|
-
from ..utils import UniqueIdentifierRangeMap
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
def get_logger():
|
|
@@ -192,7 +191,6 @@ class SQLiteInterface:
|
|
|
192
191
|
*,
|
|
193
192
|
index_names: list[str],
|
|
194
193
|
time_index_name: str,
|
|
195
|
-
**_: Any,
|
|
196
194
|
) -> None:
|
|
197
195
|
self._validate_index(index_names, time_index_name)
|
|
198
196
|
if df.empty:
|
|
@@ -254,8 +252,6 @@ class SQLiteInterface:
|
|
|
254
252
|
dimension_filters: dict[str, list[Any]] | None = None,
|
|
255
253
|
index_coordinates: list[dict[str, Any]] | None = None,
|
|
256
254
|
dimension_range_map: list[dict[str, Any]] | None = None,
|
|
257
|
-
ids: list[str] | None = None,
|
|
258
|
-
unique_identifier_range_map: dict[str, dict[str, Any]] | None = None,
|
|
259
255
|
max_rows: int | None = None,
|
|
260
256
|
now: datetime.datetime | None = None,
|
|
261
257
|
) -> tuple[
|
|
@@ -265,42 +261,9 @@ class SQLiteInterface:
|
|
|
265
261
|
dict[str, Any],
|
|
266
262
|
]:
|
|
267
263
|
self._validate_index(index_names, time_index_name)
|
|
268
|
-
identity_dimensions = [name for name in index_names if name != time_index_name]
|
|
269
|
-
uses_legacy_unique_identifier = identity_dimensions == ["unique_identifier"]
|
|
270
|
-
|
|
271
|
-
if ids is not None and unique_identifier_range_map is not None:
|
|
272
|
-
raise ValueError("Cannot provide both 'ids' and 'unique_identifier_range_map'.")
|
|
273
|
-
if ids is not None and not uses_legacy_unique_identifier:
|
|
274
|
-
raise ValueError("Legacy 'ids' reads are valid only for unique_identifier tables.")
|
|
275
|
-
if unique_identifier_range_map is not None and not uses_legacy_unique_identifier:
|
|
276
|
-
raise ValueError(
|
|
277
|
-
"Legacy 'unique_identifier_range_map' reads are valid only for "
|
|
278
|
-
"unique_identifier tables."
|
|
279
|
-
)
|
|
280
|
-
if unique_identifier_range_map is not None and dimension_range_map is not None:
|
|
281
|
-
raise ValueError(
|
|
282
|
-
"Cannot provide both 'unique_identifier_range_map' and 'dimension_range_map'."
|
|
283
|
-
)
|
|
284
|
-
|
|
285
264
|
normalized_dimension_range_map = (
|
|
286
265
|
None if dimension_range_map is None else [dict(item) for item in dimension_range_map]
|
|
287
266
|
)
|
|
288
|
-
if ids and normalized_dimension_range_map is None:
|
|
289
|
-
normalized_dimension_range_map = [
|
|
290
|
-
{
|
|
291
|
-
"coordinate": {"unique_identifier": uid},
|
|
292
|
-
"start_date": start,
|
|
293
|
-
"start_date_operand": ">=",
|
|
294
|
-
"end_date": end or now,
|
|
295
|
-
"end_date_operand": "<=",
|
|
296
|
-
}
|
|
297
|
-
for uid in ids
|
|
298
|
-
]
|
|
299
|
-
if unique_identifier_range_map is not None:
|
|
300
|
-
normalized_dimension_range_map = [
|
|
301
|
-
{"coordinate": {"unique_identifier": uid}, **dict(info)}
|
|
302
|
-
for uid, info in unique_identifier_range_map.items()
|
|
303
|
-
]
|
|
304
267
|
|
|
305
268
|
diagnostics = {
|
|
306
269
|
"limited": False,
|
|
@@ -324,42 +287,9 @@ class SQLiteInterface:
|
|
|
324
287
|
dimension_filters: dict[str, list[Any]] | None = None,
|
|
325
288
|
index_coordinates: list[dict[str, Any]] | None = None,
|
|
326
289
|
dimension_range_map: list[dict[str, Any]] | None = None,
|
|
327
|
-
ids: list[str] | None = None,
|
|
328
290
|
columns: list[str] | None = None,
|
|
329
|
-
unique_identifier_range_map: UniqueIdentifierRangeMap | None = None,
|
|
330
|
-
column_range_descriptor: dict[str, UniqueIdentifierRangeMap] | None = None,
|
|
331
|
-
**_: Any,
|
|
332
291
|
) -> pd.DataFrame:
|
|
333
292
|
self._validate_index(index_names, time_index_name)
|
|
334
|
-
identity_dimensions = [name for name in index_names if name != time_index_name]
|
|
335
|
-
uses_legacy_unique_identifier = identity_dimensions == ["unique_identifier"]
|
|
336
|
-
|
|
337
|
-
if ids is not None and unique_identifier_range_map is not None:
|
|
338
|
-
raise ValueError("Cannot provide both 'ids' and 'unique_identifier_range_map'.")
|
|
339
|
-
if ids is not None and not uses_legacy_unique_identifier:
|
|
340
|
-
raise ValueError("Legacy 'ids' reads are valid only for unique_identifier tables.")
|
|
341
|
-
if unique_identifier_range_map is not None and not uses_legacy_unique_identifier:
|
|
342
|
-
raise ValueError(
|
|
343
|
-
"Legacy 'unique_identifier_range_map' reads are valid only for "
|
|
344
|
-
"unique_identifier tables."
|
|
345
|
-
)
|
|
346
|
-
if unique_identifier_range_map is not None and dimension_range_map is not None:
|
|
347
|
-
raise ValueError(
|
|
348
|
-
"Cannot provide both 'unique_identifier_range_map' and 'dimension_range_map'."
|
|
349
|
-
)
|
|
350
|
-
if column_range_descriptor is not None:
|
|
351
|
-
raise NotImplementedError("SQLite column_range_descriptor reads are not supported.")
|
|
352
|
-
|
|
353
|
-
if ids:
|
|
354
|
-
dimension_filters = dict(dimension_filters or {})
|
|
355
|
-
if "unique_identifier" in dimension_filters:
|
|
356
|
-
raise ValueError("Cannot provide both 'ids' and a unique_identifier filter.")
|
|
357
|
-
dimension_filters["unique_identifier"] = list(ids)
|
|
358
|
-
if unique_identifier_range_map is not None:
|
|
359
|
-
dimension_range_map = [
|
|
360
|
-
{"coordinate": {"unique_identifier": uid}, **dict(info)}
|
|
361
|
-
for uid, info in unique_identifier_range_map.items()
|
|
362
|
-
]
|
|
363
293
|
|
|
364
294
|
if not self.table_exists(table):
|
|
365
295
|
logger.warning(f"Table '{table}' does not exist in {self.db_path}.")
|
|
@@ -382,6 +312,7 @@ class SQLiteInterface:
|
|
|
382
312
|
sql_parts = [f"SELECT {select_sql} FROM {self._qident(table)}"]
|
|
383
313
|
where_clauses: list[str] = []
|
|
384
314
|
params: list[Any] = []
|
|
315
|
+
identity_dimensions = [name for name in index_names if name != time_index_name]
|
|
385
316
|
|
|
386
317
|
def validate_dimension_name(name: str) -> None:
|
|
387
318
|
if name not in identity_dimensions:
|