GeneralManager 0.60.0__tar.gz → 0.60.2__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.
- {generalmanager-0.60.0/src/GeneralManager.egg-info → generalmanager-0.60.2}/PKG-INFO +1 -1
- {generalmanager-0.60.0 → generalmanager-0.60.2}/pyproject.toml +1 -1
- {generalmanager-0.60.0 → generalmanager-0.60.2/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/property.py +4 -1
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/database_bucket.py +267 -20
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/cache_decorator.py +188 -4
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/cache_tracker.py +72 -6
- generalmanager-0.60.2/src/general_manager/cache/dependency_cache.py +576 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_index.py +9 -9
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_matching.py +128 -5
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_publish.py +225 -13
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/dependency_shards.py +41 -38
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/run_context.py +218 -4
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/signals.py +7 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/base_interface.py +253 -16
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/calculation/lifecycle.py +1 -7
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/core/utils.py +1 -14
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/support.py +160 -5
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +223 -9
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/general_manager.py +197 -45
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/meta.py +126 -5
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/measurement/measurement.py +189 -34
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/json_encoder.py +3 -1
- generalmanager-0.60.2/src/general_manager/utils/make_cache_key.py +159 -0
- generalmanager-0.60.0/src/general_manager/cache/dependency_cache.py +0 -287
- generalmanager-0.60.0/src/general_manager/utils/make_cache_key.py +0 -43
- {generalmanager-0.60.0 → generalmanager-0.60.2}/LICENSE +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/README.md +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/setup.cfg +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/dataframes.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_prefetch.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_search.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_warmup.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_warmup_registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/apps.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/indexing.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/audit.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/bootstrap.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/checks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/consumer.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/errors.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/__main__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/baseline.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/diagnostics.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/fingerprints.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/fixtures.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/contract.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/readiness.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/runner.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/evals/traces.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/grounding.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/models.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/_shared.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/anthropic.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/base.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/google.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/ollama.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/providers/openai.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/rate_limits.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/routing.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/schema_index.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/settings.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/signals.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/system_prompt.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/tool_metadata.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/tools.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/chat/views.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/conf.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/dataframes/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/dataframes/measurements.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/logging.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/chat_cleanup.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/graphql_warmup.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/search_reconcile.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0004_search_index_state.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/models.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/py.typed +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/models.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/reconciliation.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/tasks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/args_to_kwargs.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/none_to_zero.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/testing.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/tests/test_settings.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/tests/test_urls.py +0 -0
- {generalmanager-0.60.0 → generalmanager-0.60.2}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.60.
|
|
3
|
+
Version: 0.60.2
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.60.
|
|
7
|
+
version = "0.60.2"
|
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.60.
|
|
3
|
+
Version: 0.60.2
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -142,7 +142,10 @@ class GraphQLProperty(property):
|
|
|
142
142
|
@wraps(fget)
|
|
143
143
|
def resolver(instance: object) -> object:
|
|
144
144
|
"""Resolve the property through the selected cached wrapper."""
|
|
145
|
-
|
|
145
|
+
cached_fget = self._cached_fget
|
|
146
|
+
if cached_fget is None:
|
|
147
|
+
cached_fget = self._get_cached_fget()
|
|
148
|
+
return cached_fget(instance)
|
|
146
149
|
|
|
147
150
|
super().__init__(resolver, doc=doc)
|
|
148
151
|
self.is_graphql_resolver = True
|
{generalmanager-0.60.0 → generalmanager-0.60.2}/src/general_manager/bucket/database_bucket.py
RENAMED
|
@@ -11,7 +11,10 @@ from django.db.models.sql.query import Query
|
|
|
11
11
|
|
|
12
12
|
from general_manager.bucket.base_bucket import Bucket
|
|
13
13
|
from general_manager.cache.cache_tracker import DependencyTracker
|
|
14
|
-
from general_manager.cache.dependency_index import
|
|
14
|
+
from general_manager.cache.dependency_index import (
|
|
15
|
+
Dependency,
|
|
16
|
+
serialize_dependency_identifier,
|
|
17
|
+
)
|
|
15
18
|
from general_manager.cache.run_context import current_calculation_run_context
|
|
16
19
|
from general_manager.manager.general_manager import GeneralManager
|
|
17
20
|
from general_manager.utils.filter_parser import create_filter_function
|
|
@@ -27,6 +30,9 @@ QueryAnnotationCallable = Callable[
|
|
|
27
30
|
models.QuerySet[models.Model],
|
|
28
31
|
]
|
|
29
32
|
MAX_RUN_SCOPED_BUCKET_RESULT_ROWS = 1000
|
|
33
|
+
_QUERY_SIGNATURE_NOT_COMPUTED = object()
|
|
34
|
+
_FIRST_ROW_CACHE_MISS = object()
|
|
35
|
+
_FIRST_ROW_CACHE_NONE = object()
|
|
30
36
|
|
|
31
37
|
|
|
32
38
|
class DatabaseBucketTypeMismatchError(TypeError):
|
|
@@ -251,6 +257,79 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
251
257
|
self._sort_keys = sort_keys
|
|
252
258
|
self._sort_reverse = sort_reverse
|
|
253
259
|
self._run_scoped_cacheable = run_scoped_cacheable
|
|
260
|
+
self._query_signature_cache: tuple[Hashable, ...] | None | object = (
|
|
261
|
+
_QUERY_SIGNATURE_NOT_COMPUTED
|
|
262
|
+
)
|
|
263
|
+
self._trusted_query_signature: Hashable | None = None
|
|
264
|
+
|
|
265
|
+
def _set_trusted_query_signature(self, signature: Hashable | None) -> None:
|
|
266
|
+
"""Set an internal non-SQL signature for framework-built querysets."""
|
|
267
|
+
self._trusted_query_signature = signature
|
|
268
|
+
self._query_signature_cache = _QUERY_SIGNATURE_NOT_COMPUTED
|
|
269
|
+
|
|
270
|
+
def _copy_for_run_context_reuse(self) -> DatabaseBucket[GeneralManagerType]:
|
|
271
|
+
"""Return an unexposed bucket copy that reuses the same trusted queryset."""
|
|
272
|
+
|
|
273
|
+
bucket = self.__class__(
|
|
274
|
+
self._data,
|
|
275
|
+
self._manager_class,
|
|
276
|
+
self.filters,
|
|
277
|
+
self.excludes,
|
|
278
|
+
search_date=self._search_date,
|
|
279
|
+
sort_keys=self._sort_keys,
|
|
280
|
+
sort_reverse=self._sort_reverse,
|
|
281
|
+
run_scoped_cacheable=self._run_scoped_cacheable,
|
|
282
|
+
)
|
|
283
|
+
bucket._set_trusted_query_signature(self._trusted_query_signature)
|
|
284
|
+
return bucket
|
|
285
|
+
|
|
286
|
+
@staticmethod
|
|
287
|
+
def _freeze_trusted_signature_payload(value: object) -> Hashable:
|
|
288
|
+
if isinstance(value, Mapping):
|
|
289
|
+
return tuple(
|
|
290
|
+
(
|
|
291
|
+
str(key),
|
|
292
|
+
DatabaseBucket._freeze_trusted_signature_payload(item_value),
|
|
293
|
+
)
|
|
294
|
+
for key, item_value in sorted(
|
|
295
|
+
value.items(),
|
|
296
|
+
key=lambda item: str(item[0]),
|
|
297
|
+
)
|
|
298
|
+
)
|
|
299
|
+
if isinstance(value, (list, tuple)):
|
|
300
|
+
return tuple(
|
|
301
|
+
DatabaseBucket._freeze_trusted_signature_payload(item) for item in value
|
|
302
|
+
)
|
|
303
|
+
if isinstance(value, (set, frozenset)):
|
|
304
|
+
return tuple(
|
|
305
|
+
sorted(
|
|
306
|
+
(
|
|
307
|
+
DatabaseBucket._freeze_trusted_signature_payload(item)
|
|
308
|
+
for item in value
|
|
309
|
+
),
|
|
310
|
+
key=repr,
|
|
311
|
+
)
|
|
312
|
+
)
|
|
313
|
+
if isinstance(value, models.Model):
|
|
314
|
+
return ("model", value.__class__, value.pk)
|
|
315
|
+
try:
|
|
316
|
+
hash(value)
|
|
317
|
+
except TypeError:
|
|
318
|
+
return ("serialized", serialize_dependency_identifier(value))
|
|
319
|
+
return value
|
|
320
|
+
|
|
321
|
+
def _trusted_query_signature_with(
|
|
322
|
+
self,
|
|
323
|
+
operation: str,
|
|
324
|
+
kwargs: Mapping[str, object],
|
|
325
|
+
) -> Hashable | None:
|
|
326
|
+
if self._trusted_query_signature is None:
|
|
327
|
+
return None
|
|
328
|
+
return (
|
|
329
|
+
self._trusted_query_signature,
|
|
330
|
+
operation,
|
|
331
|
+
self._freeze_trusted_signature_payload(kwargs),
|
|
332
|
+
)
|
|
254
333
|
|
|
255
334
|
def __reduce__(self) -> str | tuple[object, ...]:
|
|
256
335
|
"""
|
|
@@ -365,27 +444,50 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
365
444
|
tuple[Hashable, ...] | None: Cache key components for equivalent
|
|
366
445
|
queryset results, or ``None`` when reuse should be bypassed.
|
|
367
446
|
"""
|
|
447
|
+
if self._query_signature_cache is not _QUERY_SIGNATURE_NOT_COMPUTED:
|
|
448
|
+
return cast(tuple[Hashable, ...] | None, self._query_signature_cache)
|
|
368
449
|
if not self._run_scoped_cacheable:
|
|
450
|
+
self._query_signature_cache = None
|
|
369
451
|
return None
|
|
452
|
+
if self._trusted_query_signature is not None:
|
|
453
|
+
signature = (
|
|
454
|
+
self._manager_class,
|
|
455
|
+
self._data.model,
|
|
456
|
+
self._data.db,
|
|
457
|
+
"trusted",
|
|
458
|
+
self._trusted_query_signature,
|
|
459
|
+
self._search_date,
|
|
460
|
+
self._sort_keys,
|
|
461
|
+
self._sort_reverse,
|
|
462
|
+
)
|
|
463
|
+
self._query_signature_cache = signature
|
|
464
|
+
return signature
|
|
370
465
|
query = self._data.query
|
|
371
466
|
if not isinstance(query, Query):
|
|
467
|
+
self._query_signature_cache = None
|
|
372
468
|
return None
|
|
373
469
|
if query.select_for_update:
|
|
470
|
+
self._query_signature_cache = None
|
|
374
471
|
return None
|
|
375
472
|
if query.combinator:
|
|
473
|
+
self._query_signature_cache = None
|
|
376
474
|
return None
|
|
377
475
|
if query.distinct:
|
|
476
|
+
self._query_signature_cache = None
|
|
378
477
|
return None
|
|
379
478
|
if getattr(self._data, "_prefetch_related_lookups", ()):
|
|
479
|
+
self._query_signature_cache = None
|
|
380
480
|
return None
|
|
381
481
|
deferred_loading = getattr(query, "deferred_loading", None)
|
|
382
482
|
if isinstance(deferred_loading, tuple) and deferred_loading[0]:
|
|
483
|
+
self._query_signature_cache = None
|
|
383
484
|
return None
|
|
384
485
|
try:
|
|
385
486
|
sql, params = self._data.query.sql_with_params()
|
|
386
487
|
except (EmptyResultSet, FieldError, TypeError, ValueError):
|
|
488
|
+
self._query_signature_cache = None
|
|
387
489
|
return None
|
|
388
|
-
|
|
490
|
+
signature = (
|
|
389
491
|
self._manager_class,
|
|
390
492
|
self._data.model,
|
|
391
493
|
self._data.db,
|
|
@@ -395,6 +497,8 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
395
497
|
self._sort_keys,
|
|
396
498
|
self._sort_reverse,
|
|
397
499
|
)
|
|
500
|
+
self._query_signature_cache = signature
|
|
501
|
+
return signature
|
|
398
502
|
|
|
399
503
|
def _bucket_index_source_signature(self) -> Hashable:
|
|
400
504
|
"""Return a queryset signature when safe, otherwise use object identity."""
|
|
@@ -501,6 +605,65 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
501
605
|
return None
|
|
502
606
|
return cast(tuple[models.Model, ...], cached)
|
|
503
607
|
|
|
608
|
+
def _can_cache_run_scoped_managers(self) -> bool:
|
|
609
|
+
if self._manager_class.__init__ is not GeneralManager.__init__:
|
|
610
|
+
return False
|
|
611
|
+
if not type.__getattribute__(
|
|
612
|
+
self._manager_class,
|
|
613
|
+
"_gm_uses_default_identification_dependency_active",
|
|
614
|
+
):
|
|
615
|
+
return False
|
|
616
|
+
return callable(
|
|
617
|
+
getattr(self._manager_class.Interface, "_from_trusted_orm_instance", None)
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
def _manager_identification_dependencies(
|
|
621
|
+
self,
|
|
622
|
+
managers: tuple[GeneralManagerType, ...],
|
|
623
|
+
) -> frozenset[Dependency]:
|
|
624
|
+
manager_name = type.__getattribute__(self._manager_class, "__name__")
|
|
625
|
+
return frozenset(
|
|
626
|
+
(
|
|
627
|
+
manager_name,
|
|
628
|
+
"identification",
|
|
629
|
+
serialize_dependency_identifier(manager.identification),
|
|
630
|
+
)
|
|
631
|
+
for manager in managers
|
|
632
|
+
)
|
|
633
|
+
|
|
634
|
+
def _get_run_scoped_managers(self) -> tuple[GeneralManagerType, ...] | None:
|
|
635
|
+
"""Load or reuse manager wrappers for a trusted row snapshot."""
|
|
636
|
+
if not self._can_cache_run_scoped_managers():
|
|
637
|
+
return None
|
|
638
|
+
context = current_calculation_run_context()
|
|
639
|
+
if context is None:
|
|
640
|
+
return None
|
|
641
|
+
signature = self._query_signature()
|
|
642
|
+
if signature is None:
|
|
643
|
+
return None
|
|
644
|
+
cached = context.get_orm_bucket_managers(signature)
|
|
645
|
+
if cached is not None:
|
|
646
|
+
managers = cast(tuple[GeneralManagerType, ...], cached)
|
|
647
|
+
dependencies = context.get_orm_bucket_manager_dependencies(signature)
|
|
648
|
+
if dependencies is not None:
|
|
649
|
+
DependencyTracker._track_many_validated(dependencies)
|
|
650
|
+
else:
|
|
651
|
+
for manager in managers:
|
|
652
|
+
self._manager_class._track_identification_dependency(
|
|
653
|
+
manager.identification
|
|
654
|
+
)
|
|
655
|
+
return managers
|
|
656
|
+
rows = self._get_run_scoped_rows()
|
|
657
|
+
if rows is None:
|
|
658
|
+
return None
|
|
659
|
+
managers = tuple(self._build_manager_from_instance(row) for row in rows)
|
|
660
|
+
context.set_orm_bucket_managers(
|
|
661
|
+
signature,
|
|
662
|
+
managers,
|
|
663
|
+
self._manager_identification_dependencies(managers),
|
|
664
|
+
)
|
|
665
|
+
return managers
|
|
666
|
+
|
|
504
667
|
@staticmethod
|
|
505
668
|
def _snapshot_get_primary_key(
|
|
506
669
|
kwargs: Mapping[str, LookupValue],
|
|
@@ -528,21 +691,42 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
528
691
|
return kwargs["id"]
|
|
529
692
|
return None
|
|
530
693
|
|
|
694
|
+
def _can_materialize_count_snapshot(self) -> bool:
|
|
695
|
+
"""Return whether count/len may populate a bounded run-scoped snapshot."""
|
|
696
|
+
context = current_calculation_run_context()
|
|
697
|
+
if context is None:
|
|
698
|
+
return False
|
|
699
|
+
query = getattr(self._data, "query", None)
|
|
700
|
+
if not isinstance(query, Query):
|
|
701
|
+
return False
|
|
702
|
+
where = getattr(query, "where", None)
|
|
703
|
+
children = getattr(where, "children", None)
|
|
704
|
+
return bool(children)
|
|
705
|
+
|
|
531
706
|
def _track_effective_dependencies(self) -> None:
|
|
532
707
|
"""Record the bucket's effective filter/exclude state when it is evaluated."""
|
|
533
|
-
manager_name = self._manager_class
|
|
534
|
-
|
|
535
|
-
|
|
708
|
+
manager_name = type.__getattribute__(self._manager_class, "__name__")
|
|
709
|
+
needs_sort_payload = bool(self._sort_keys)
|
|
710
|
+
normalized_filters = (
|
|
711
|
+
self._normalize_dependency_mapping(self.filters)
|
|
712
|
+
if self.filters or needs_sort_payload
|
|
713
|
+
else {}
|
|
714
|
+
)
|
|
715
|
+
normalized_excludes = (
|
|
716
|
+
self._normalize_dependency_mapping(self.excludes)
|
|
717
|
+
if self.excludes or needs_sort_payload
|
|
718
|
+
else {}
|
|
719
|
+
)
|
|
536
720
|
if self.filters:
|
|
537
|
-
DependencyTracker.
|
|
721
|
+
DependencyTracker._track_validated(
|
|
538
722
|
manager_name,
|
|
539
723
|
"filter",
|
|
540
724
|
serialize_dependency_identifier(normalized_filters),
|
|
541
725
|
)
|
|
542
726
|
else:
|
|
543
|
-
DependencyTracker.
|
|
727
|
+
DependencyTracker._track_validated(manager_name, "all", "")
|
|
544
728
|
if self.excludes:
|
|
545
|
-
DependencyTracker.
|
|
729
|
+
DependencyTracker._track_validated(
|
|
546
730
|
manager_name,
|
|
547
731
|
"exclude",
|
|
548
732
|
serialize_dependency_identifier(normalized_excludes),
|
|
@@ -554,7 +738,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
554
738
|
"excludes": normalized_excludes,
|
|
555
739
|
"reverse": self._sort_reverse,
|
|
556
740
|
}
|
|
557
|
-
DependencyTracker.
|
|
741
|
+
DependencyTracker._track_validated(
|
|
558
742
|
manager_name,
|
|
559
743
|
"filter",
|
|
560
744
|
serialize_dependency_identifier({f"__sort__{sort_key}": payload}),
|
|
@@ -576,6 +760,10 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
576
760
|
GeneralManagerType: Manager instance for each primary key in the queryset.
|
|
577
761
|
"""
|
|
578
762
|
self._track_effective_dependencies()
|
|
763
|
+
managers = self._get_run_scoped_managers()
|
|
764
|
+
if managers is not None:
|
|
765
|
+
yield from managers
|
|
766
|
+
return
|
|
579
767
|
rows = self._get_run_scoped_rows()
|
|
580
768
|
if rows is not None:
|
|
581
769
|
for row in rows:
|
|
@@ -782,7 +970,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
782
970
|
qs = qs.filter(pk__in=ids)
|
|
783
971
|
|
|
784
972
|
merged_filter = self.__merge_filter_definitions(self.filters, **kwargs)
|
|
785
|
-
|
|
973
|
+
bucket = self.__class__(
|
|
786
974
|
qs,
|
|
787
975
|
self._manager_class,
|
|
788
976
|
merged_filter,
|
|
@@ -792,6 +980,11 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
792
980
|
sort_reverse=self._sort_reverse,
|
|
793
981
|
run_scoped_cacheable=self._run_scoped_cacheable,
|
|
794
982
|
)
|
|
983
|
+
if not annotations and not python_filters:
|
|
984
|
+
bucket._set_trusted_query_signature(
|
|
985
|
+
self._trusted_query_signature_with("filter", orm_kwargs)
|
|
986
|
+
)
|
|
987
|
+
return bucket
|
|
795
988
|
|
|
796
989
|
def exclude(self, **kwargs: LookupValue) -> DatabaseBucket[GeneralManagerType]:
|
|
797
990
|
"""
|
|
@@ -843,7 +1036,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
843
1036
|
qs = qs.exclude(pk__in=ids)
|
|
844
1037
|
|
|
845
1038
|
merged_exclude = self.__merge_filter_definitions(self.excludes, **kwargs)
|
|
846
|
-
|
|
1039
|
+
bucket = self.__class__(
|
|
847
1040
|
qs,
|
|
848
1041
|
self._manager_class,
|
|
849
1042
|
self.filters,
|
|
@@ -853,6 +1046,11 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
853
1046
|
sort_reverse=self._sort_reverse,
|
|
854
1047
|
run_scoped_cacheable=self._run_scoped_cacheable,
|
|
855
1048
|
)
|
|
1049
|
+
if not annotations and not python_filters:
|
|
1050
|
+
bucket._set_trusted_query_signature(
|
|
1051
|
+
self._trusted_query_signature_with("exclude", orm_kwargs)
|
|
1052
|
+
)
|
|
1053
|
+
return bucket
|
|
856
1054
|
|
|
857
1055
|
def first(self) -> GeneralManagerType | None:
|
|
858
1056
|
"""
|
|
@@ -875,7 +1073,23 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
875
1073
|
if not primary_keys:
|
|
876
1074
|
return None
|
|
877
1075
|
return self._build_manager_from_primary_key(primary_keys[0])
|
|
1076
|
+
context = current_calculation_run_context()
|
|
1077
|
+
signature = self._query_signature() if context is not None else None
|
|
1078
|
+
if context is not None and signature is not None:
|
|
1079
|
+
cached = context.get_orm_bucket_first_row(
|
|
1080
|
+
signature,
|
|
1081
|
+
_FIRST_ROW_CACHE_MISS,
|
|
1082
|
+
)
|
|
1083
|
+
if cached is _FIRST_ROW_CACHE_NONE:
|
|
1084
|
+
return None
|
|
1085
|
+
if cached is not _FIRST_ROW_CACHE_MISS:
|
|
1086
|
+
return self._build_manager_from_instance(cast(models.Model, cached))
|
|
878
1087
|
first_element = self._data.first()
|
|
1088
|
+
if context is not None and signature is not None:
|
|
1089
|
+
context.set_orm_bucket_first_row(
|
|
1090
|
+
signature,
|
|
1091
|
+
_FIRST_ROW_CACHE_NONE if first_element is None else first_element,
|
|
1092
|
+
)
|
|
879
1093
|
if first_element is None:
|
|
880
1094
|
return None
|
|
881
1095
|
return self._build_manager_from_instance(first_element)
|
|
@@ -917,6 +1131,10 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
917
1131
|
int: Number of represented rows.
|
|
918
1132
|
"""
|
|
919
1133
|
self._track_effective_dependencies()
|
|
1134
|
+
if self._can_materialize_count_snapshot():
|
|
1135
|
+
rows = self._get_run_scoped_rows()
|
|
1136
|
+
if rows is not None:
|
|
1137
|
+
return len(rows)
|
|
920
1138
|
primary_keys = self._peek_run_scoped_primary_keys()
|
|
921
1139
|
if primary_keys is not None:
|
|
922
1140
|
return len(primary_keys)
|
|
@@ -932,7 +1150,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
932
1150
|
Returns:
|
|
933
1151
|
DatabaseBucket[GeneralManagerType]: Bucket encapsulating `self._data.all()`.
|
|
934
1152
|
"""
|
|
935
|
-
|
|
1153
|
+
bucket = self.__class__(
|
|
936
1154
|
self._data.all(),
|
|
937
1155
|
self._manager_class,
|
|
938
1156
|
self.filters,
|
|
@@ -942,6 +1160,8 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
942
1160
|
sort_reverse=self._sort_reverse,
|
|
943
1161
|
run_scoped_cacheable=self._run_scoped_cacheable,
|
|
944
1162
|
)
|
|
1163
|
+
bucket._set_trusted_query_signature(self._trusted_query_signature)
|
|
1164
|
+
return bucket
|
|
945
1165
|
|
|
946
1166
|
def get(self, **kwargs: LookupValue) -> GeneralManagerType:
|
|
947
1167
|
"""
|
|
@@ -1027,21 +1247,43 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
1027
1247
|
return self._build_manager_from_primary_key(primary_keys[item])
|
|
1028
1248
|
return self._build_manager_from_instance(self._data[item])
|
|
1029
1249
|
|
|
1250
|
+
def __bool__(self) -> bool:
|
|
1251
|
+
"""
|
|
1252
|
+
Return whether the bucket contains at least one row without counting all rows.
|
|
1253
|
+
|
|
1254
|
+
Truthiness is an existence check, not a cardinality request. Reuse any
|
|
1255
|
+
active run-context snapshot first, then cache a queryset ``exists()``
|
|
1256
|
+
result for equivalent trusted querysets in the same calculation run.
|
|
1257
|
+
"""
|
|
1258
|
+
self._track_effective_dependencies()
|
|
1259
|
+
rows = self._peek_run_scoped_rows()
|
|
1260
|
+
if rows is not None:
|
|
1261
|
+
return bool(rows)
|
|
1262
|
+
primary_keys = self._peek_run_scoped_primary_keys()
|
|
1263
|
+
if primary_keys is not None:
|
|
1264
|
+
return bool(primary_keys)
|
|
1265
|
+
context = current_calculation_run_context()
|
|
1266
|
+
signature = self._query_signature() if context is not None else None
|
|
1267
|
+
if context is not None and signature is not None:
|
|
1268
|
+
cached = context.get_orm_bucket_exists(signature)
|
|
1269
|
+
if cached is not None:
|
|
1270
|
+
return bool(cached)
|
|
1271
|
+
exists = bool(self._data.exists())
|
|
1272
|
+
if context is not None and signature is not None:
|
|
1273
|
+
context.set_orm_bucket_exists(signature, exists)
|
|
1274
|
+
return exists
|
|
1275
|
+
|
|
1030
1276
|
def __len__(self) -> int:
|
|
1031
1277
|
"""
|
|
1032
1278
|
Return the number of rows represented by the bucket.
|
|
1033
1279
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1280
|
+
Delegates to `count()` so dependency tracking, run-scoped snapshots, and
|
|
1281
|
+
queryset fallback behavior stay aligned between both cardinality paths.
|
|
1036
1282
|
|
|
1037
1283
|
Returns:
|
|
1038
1284
|
int: Number of represented rows.
|
|
1039
1285
|
"""
|
|
1040
|
-
self.
|
|
1041
|
-
primary_keys = self._peek_run_scoped_primary_keys()
|
|
1042
|
-
if primary_keys is not None:
|
|
1043
|
-
return len(primary_keys)
|
|
1044
|
-
return int(self._data.count())
|
|
1286
|
+
return self.count()
|
|
1045
1287
|
|
|
1046
1288
|
def __str__(self) -> str:
|
|
1047
1289
|
"""
|
|
@@ -1169,7 +1411,7 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
1169
1411
|
except (FieldError, TypeError, ValueError) as error:
|
|
1170
1412
|
raise QuerysetOrderingError(error) from error
|
|
1171
1413
|
|
|
1172
|
-
|
|
1414
|
+
bucket = self.__class__(
|
|
1173
1415
|
qs,
|
|
1174
1416
|
self._manager_class,
|
|
1175
1417
|
self.filters,
|
|
@@ -1179,6 +1421,9 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
1179
1421
|
sort_reverse=reverse,
|
|
1180
1422
|
run_scoped_cacheable=self._run_scoped_cacheable,
|
|
1181
1423
|
)
|
|
1424
|
+
if not annotations and not python_keys:
|
|
1425
|
+
bucket._set_trusted_query_signature(self._trusted_query_signature)
|
|
1426
|
+
return bucket
|
|
1182
1427
|
|
|
1183
1428
|
def none(self) -> DatabaseBucket[GeneralManagerType]:
|
|
1184
1429
|
"""
|
|
@@ -1193,4 +1438,6 @@ class DatabaseBucket(Bucket[GeneralManagerType]):
|
|
|
1193
1438
|
"""
|
|
1194
1439
|
own = self.all()
|
|
1195
1440
|
own._data = own._data.none()
|
|
1441
|
+
own._query_signature_cache = _QUERY_SIGNATURE_NOT_COMPUTED
|
|
1442
|
+
own._trusted_query_signature = None
|
|
1196
1443
|
return own
|