lsst-daf-butler 29.2025.2400__tar.gz → 29.2025.2500__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.
- {lsst_daf_butler-29.2025.2400/python/lsst_daf_butler.egg-info → lsst_daf_butler-29.2025.2500}/PKG-INFO +1 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/CHANGES.rst +71 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/pyproject.toml +1 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/_datastore.py +2 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/stored_file_info.py +31 -12
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/chainedDatastore.py +3 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_butler/_direct_butler.py +5 -6
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/_driver.py +1 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_config.py +21 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/databases/postgresql.py +15 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/databases/sqlite.py +16 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_database.py +21 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/_config.py +5 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/_records.py +3 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/sql_registry.py +5 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/tests/_registry.py +59 -46
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_http_connection.py +6 -2
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_remote_file_transfer_source.py +49 -7
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/_factory.py +4 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/handlers/_external.py +67 -9
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/handlers/_external_query.py +24 -11
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/remote_butler/server/handlers/_query_limits.py +105 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/handlers/_query_streaming.py +11 -47
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/handlers/_utils.py +15 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server_models.py +1 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/butler_queries.py +50 -43
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/__init__.py +0 -0
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/base.yaml +81 -0
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset-skymap.yaml +45 -0
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/ci_hsc-subset.yaml +732 -0
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/datasets.yaml +138 -0
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/hsc-rc2-subset-v0.yaml +159 -0
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/spatial.py +617 -0
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/tests/registry_data/spatial.yaml +192 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/utils.py +12 -3
- lsst_daf_butler-29.2025.2500/python/lsst/daf/butler/version.py +2 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500/python/lsst_daf_butler.egg-info}/PKG-INFO +1 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst_daf_butler.egg-info/SOURCES.txt +9 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_butler.py +19 -6
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdQueryCollections.py +2 -5
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdQueryDataIds.py +1 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_dimension_record_containers.py +2 -3
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_postgresql.py +4 -3
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_quantumBackedButler.py +1 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_remote_butler.py +2 -1
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_server.py +87 -7
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_simpleButler.py +26 -26
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_sqlite.py +11 -7
- lsst_daf_butler-29.2025.2400/python/lsst/daf/butler/version.py +0 -2
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/COPYRIGHT +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/LICENSE +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/MANIFEST.in +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/README.md +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/bsd_license.txt +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/concreteStorageClasses.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/configuring.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/datastores.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/dimensions.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/formatters.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/index.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/organizing.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/queries.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/use-in-tests.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/writing-subcommands.rst +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/gpl-v3.0.txt +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_butler.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_butler_collections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_butler_config.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_butler_instance_options.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_butler_metrics.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_butler_repo_index.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_collection_type.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_column_categorization.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_column_tags.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_column_type_info.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_config.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_config_support.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_dataset_association.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_dataset_existence.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_dataset_provenance.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_dataset_ref.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_dataset_type.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_deferredDatasetHandle.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_exceptions.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_exceptions_legacy.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_file_dataset.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_file_descriptor.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_formatter.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_labeled_butler_factory.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_limited_butler.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_location.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_named.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_quantum.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_quantum_backed.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_query_all_datasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_registry_shim.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_storage_class.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_storage_class_delegate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_timespan.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_topology.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_utilities/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_utilities/locked_object.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_utilities/named_locks.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/_utilities/thread_safe_cache.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/arrow_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/butler.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/cliLog.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/cmd/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/cmd/_remove_collections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/cmd/_remove_runs.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/cmd/commands.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/opt/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/opt/arguments.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/opt/optionGroups.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/opt/options.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/progress.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/cli/utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/column_spec.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/datastore.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/datastores/composites.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/datastores/fileDatastore.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/datastores/formatters.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/datastores/writeRecipes.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/dimensions.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe0.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe1.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe2.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe3.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe4.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe5.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe6.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/old_dimensions/daf_butler_universe7.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/registry.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/repo_transfer_formats.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/configs/storageClasses.yaml +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/_transfer.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/cache_manager.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/composites.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/constraints.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/file_templates.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/generic_base.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastore/record_data.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/fileDatastore.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/fileDatastoreClient.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/file_datastore/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/file_datastore/get.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/file_datastore/retrieve_artifacts.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/file_datastore/transfer.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/datastores/inMemoryDatastore.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/ddl.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/delegates/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/delegates/arrowtable.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_config.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_coordinate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_data_coordinate_iterable.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_database.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_elements.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_governor.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_group.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_packer.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_record_set.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_record_table.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_records.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_schema.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_skypix.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/_universe.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/construction.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/dimensions/record_cache.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_butler/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_butler/_direct_butler_collections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/_postprocessing.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/_query_analysis.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/_query_builder.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/_result_page_converter.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/_sql_builders.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/direct_query_driver/_sql_column_visitor.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/astropyTable.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/file.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/json.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/logs.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/matplotlib.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/packages.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/parquet.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/pickle.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/typeless.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/formatters/yaml.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/json.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/logging.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/mapping_factory.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/name_shrinker.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/nonempty_mapping.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/persistence_context.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/progress.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/py.typed +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/pydantic_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_base.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_data_coordinate_query_results.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_dataset_query_results.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_dimension_record_query_results.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_expression_strings.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_general_query_results.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_identifiers.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/_query.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/convert_args.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/driver.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/expression_factory.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/overlaps.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/predicate_constraints_summary.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/result_specs.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/_base.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/_column_expression.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/_column_literal.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/_column_reference.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/_column_set.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/_predicate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/tree/_query_tree.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/queries/visitors.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_caching_context.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_collection_record_cache.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_collection_summary.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_collection_summary_cache.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_defaults.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_exceptions.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_registry.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/_registry_factory.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/attributes.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/bridge/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/bridge/ephemeral.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/bridge/monolithic.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/collections/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/collections/_base.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/collections/nameKey.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/collections/synthIntKey.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/connectionString.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/databases/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/datasets/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/datasets/byDimensions/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/datasets/byDimensions/_dataset_type_cache.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/datasets/byDimensions/_manager.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/datasets/byDimensions/summaries.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/datasets/byDimensions/tables.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/dimensions/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/dimensions/static.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_attributes.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_bridge.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_collections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_database_explain.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_datasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_dimensions.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_obscore.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_opaque.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/interfaces/_versioning.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/managers.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/nameShrinker.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/_manager.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/_schema.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/_spatial.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/default_spatial.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/obscore/pgsphere.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/opaque.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_builder.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_query.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_query_backend.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_query_context.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_readers.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_results.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_sql_query_backend.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_sql_query_context.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/_structs.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/butler_sql_engine.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/_predicate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/categorize.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/check.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/normalForm.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/exprTree.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/parser.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/parserLex.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/parserYacc.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/lex.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/ply/yacc.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/expressions/parser/treeVisitor.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/queries/find_first_dataset.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/tests/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/tests/_database.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/versions.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/registry/wildcards.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_authentication.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_collection_args.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_config.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_defaults.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_errors.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_factory.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_query_driver.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_query_results.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_ref_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_registry.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_remote_butler.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/_remote_butler_collections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/registry/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/registry/_query_common.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/registry/_query_data_coordinates.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/registry/_query_datasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/registry/_query_dimension_records.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/_config.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/_dependencies.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/_gafaelfawr.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/_server.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/_telemetry.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/handlers/_internal.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/remote_butler/server/handlers/_query_serialization.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/repo_relocation.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/_associate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/_pruneDatasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/butlerImport.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/certifyCalibrations.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/collectionChain.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/configDump.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/configValidate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/createRepo.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/exportCalibs.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/ingest_files.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/ingest_zip.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/queryCollections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/queryDataIds.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/queryDatasetTypes.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/queryDatasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/queryDimensionRecords.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/register_dataset_type.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/removeCollections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/removeDatasetType.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/removeRuns.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/retrieveArtifacts.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/script/transferDatasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/_datasetsHelper.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/_dummyRegistry.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/_examplePythonTypes.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/_testRepo.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/cliCmdTestBase.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/cliLogTestBase.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/deferredFormatter.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/dict_convertible_model.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/hybrid_butler.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/hybrid_butler_collections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/hybrid_butler_registry.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/postgresql.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/server.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/server_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/tests/testFormatters.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/time_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/timespan_database_representation.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/transfers/__init__.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/transfers/_context.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/transfers/_interfaces.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/transfers/_yaml.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst/daf/butler/utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst_daf_butler.egg-info/dependency_links.txt +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst_daf_butler.egg-info/entry_points.txt +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst_daf_butler.egg-info/requires.txt +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst_daf_butler.egg-info/top_level.txt +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/python/lsst_daf_butler.egg-info/zip-safe +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/setup.cfg +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_astropyTableFormatter.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_authentication.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_butler_factory.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdAssociate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdConfigDump.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdConfigValidate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdCreate.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdImport.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdIngestFiles.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdPruneDatasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdQueryDatasetTypes.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdQueryDatasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdQueryDimensionRecords.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdRemoveCollections.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdRemoveRuns.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliCmdRetrieveArtifacts.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliLog.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliPluginLoader.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliUtilSplitCommas.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliUtilSplitKv.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliUtilToUpper.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_cliUtils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_column_spec.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_composites.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_config.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_connectionString.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_constraints.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_datasets.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_datastore.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_ddl.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_dimensions.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_exprParserLex.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_exprParserYacc.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_expressions.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_formatter.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_gafaelfawr.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_location.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_logFormatter.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_logging.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_matplotlibFormatter.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_nonempty_mapping.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_normalFormExpression.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_obscore.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_packages.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_parquet.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_progress.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_pydantic_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_quantum.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_query_direct_postgresql.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_query_direct_sqlite.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_query_interface.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_query_relations.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_query_remote.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_query_utilities.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_storageClass.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_templates.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_testRepo.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_thread_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_time_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_timespan.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_utils.py +0 -0
- {lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/tests/test_versioning.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lsst-daf-butler
|
|
3
|
-
Version: 29.2025.
|
|
3
|
+
Version: 29.2025.2500
|
|
4
4
|
Summary: An abstraction layer for reading and writing astronomical data to datastores.
|
|
5
5
|
Author-email: Rubin Observatory Data Management <dm-admin@lists.lsst.org>
|
|
6
6
|
License: BSD 3-Clause License
|
{lsst_daf_butler-29.2025.2400 → lsst_daf_butler-29.2025.2500}/doc/lsst.daf.butler/CHANGES.rst
RENAMED
|
@@ -1,3 +1,74 @@
|
|
|
1
|
+
Butler v29.1.0 (2025-06-13)
|
|
2
|
+
===========================
|
|
3
|
+
|
|
4
|
+
New Features
|
|
5
|
+
------------
|
|
6
|
+
|
|
7
|
+
- Added support in user expressions for explicit specification of bind identifiers with a preceding colon symbol.
|
|
8
|
+
Legacy format of bind identifiers without colon is still supported, but will be deprecated in the future. (`DM-38497 <https://rubinobs.atlassian.net/browse/DM-38497>`_)
|
|
9
|
+
- Added a new ``--show-dataset-types`` argument (``-t``) to ``butler query-collections`` to list the dataset types in each collection.
|
|
10
|
+
Also added a new ``--exclude-dataset-types`` which allows a comma-separated list of string globs to be passed in for exclusion when dataset types are shown. (`DM-48975 <https://rubinobs.atlassian.net/browse/DM-48975>`_)
|
|
11
|
+
- Added Pydantic serialization for ``DimensionRecordSet``. (`DM-49622 <https://rubinobs.atlassian.net/browse/DM-49622>`_)
|
|
12
|
+
- Added ``FileDataset.to_simple`` and ``FileDataset.from_simple`` for serializing ``FileDataset`` instances. (`DM-49670 <https://rubinobs.atlassian.net/browse/DM-49670>`_)
|
|
13
|
+
- Added a ``join_data_coordinate_table`` method to the ``Query`` class for uploading data IDs from Astropy tables.
|
|
14
|
+
This includes support for filling in required-dimension columns using constraints from a ``where`` string (for example now a table with just ``visit`` IDs along with ``instrument='LSSTCam'`` in the ``where`` string will work). (`DM-49949 <https://rubinobs.atlassian.net/browse/DM-49949>`_)
|
|
15
|
+
- Added support to the user expression language for a ``GLOB(expression, pattern)`` function.
|
|
16
|
+
The function performs case-sensitive match of the string expression against the pattern.
|
|
17
|
+
The pattern can include ``*`` and ``?`` meta-characters that match any number or a single character. (`DM-50191 <https://rubinobs.atlassian.net/browse/DM-50191>`_)
|
|
18
|
+
- Added the ability for Zip ingest to register any missing dimension records.
|
|
19
|
+
Note that if any datasets use ``visit`` that require registration then the records being registered will not fully define the visit and so can not be usable for graph building.
|
|
20
|
+
It is recommended that visits be defined first before ingest at this time. (`DM-50313 <https://rubinobs.atlassian.net/browse/DM-50313>`_)
|
|
21
|
+
- Added support to the user expression language for UUID literals that can be used to query dataset IDs.
|
|
22
|
+
UUID literals are specified using function call syntax: ``UUID('hex-string')``. (`DM-50451 <https://rubinobs.atlassian.net/browse/DM-50451>`_)
|
|
23
|
+
- Added ability for Butler to record timing metrics such as the amount of time spent in ``get()`` or ``put()`` and the number of times those are called.
|
|
24
|
+
A metrics object can be given to the ``Butler`` constructor to record everything, or alternatively a new context manager ``Butler.record_metrics`` can be used to record metrics for a specific usage. (`DM-50491 <https://rubinobs.atlassian.net/browse/DM-50491>`_)
|
|
25
|
+
- ``RemoteButler`` can now be used as a source Butler in ``transfer_from``. (`DM-51075 <https://rubinobs.atlassian.net/browse/DM-51075>`_)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
API Changes
|
|
29
|
+
-----------
|
|
30
|
+
|
|
31
|
+
- * The ``unstore`` parameter for ``Butler.removeRuns()`` has been deprecated.
|
|
32
|
+
We now always remove the file artifacts when removing the collection.
|
|
33
|
+
* Added a ``unlink_from_chains`` parameter to ``Butler.removeRuns()`` to allow the RUN collections to be unlinked from their parent chains automatically. (`DM-50996 <https://rubinobs.atlassian.net/browse/DM-50996>`_)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
Bug Fixes
|
|
37
|
+
---------
|
|
38
|
+
|
|
39
|
+
- Fixed an issue where ``find_first=False`` dataset queries would sometimes return duplicate results if more than one collection was being searched. (`DM-47201 <https://rubinobs.atlassian.net/browse/DM-47201>`_)
|
|
40
|
+
- Query expressions now allow float columns to be compared with ``int`` literals.
|
|
41
|
+
Query expressions now allow ``OVERLAPS`` to be used to compare timespans with ``ingest_date.`` (`DM-47644 <https://rubinobs.atlassian.net/browse/DM-47644>`_)
|
|
42
|
+
- ``Butler.ingest()`` will now register missing run collections instead of raising a ``MissingCollectionError``. (`DM-49670 <https://rubinobs.atlassian.net/browse/DM-49670>`_)
|
|
43
|
+
- Fixed handling of expressions like ``"id=2"`` in contexts where ``"id"`` resolves unambigously to a dimension primary key column. (`DM-50465 <https://rubinobs.atlassian.net/browse/DM-50465>`_)
|
|
44
|
+
- ``butler remove-runs`` will no longer block if a parallel process calls ``butler remove-runs`` on a run contained in the same collection chain. (`DM-50855 <https://rubinobs.atlassian.net/browse/DM-50855>`_)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
Performance Enhancement
|
|
48
|
+
-----------------------
|
|
49
|
+
|
|
50
|
+
- ``Butler.transfer_from()`` now uses fewer database queries when inserting datasets of multiple dataset types, when some of the dataset types have the same dimensions. (`DM-49513 <https://rubinobs.atlassian.net/browse/DM-49513>`_)
|
|
51
|
+
- Improve the performance of certain queries by moving ``WHERE`` clause terms down into subqueries. (`DM-50969 <https://rubinobs.atlassian.net/browse/DM-50969>`_)
|
|
52
|
+
- ``Butler.transfer_from`` now uses fewer database queries. (`DM-51302 <https://rubinobs.atlassian.net/browse/DM-51302>`_)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
Other Changes and Additions
|
|
56
|
+
---------------------------
|
|
57
|
+
|
|
58
|
+
- ``retrieveArtifacts`` and ``transfer_from`` now transfer their artifacts using multiple threads. (`DM-31824 <https://rubinobs.atlassian.net/browse/DM-31824>`_)
|
|
59
|
+
- * Reorganized the code for ``Butler.ingest`` and ``Butler.ingest_zip`` to share the code from ``Butler.transfer_from`` in order to provide consistent error messages for incompatible dataset types and to allow a future possibility of registering dataset types and dimension records as part of ``ingest_zip``.
|
|
60
|
+
* Removed the ``use_cache`` parameter from the ``DimensionUniverse`` constructor.
|
|
61
|
+
The universe is always cached and the remote butler now uses that cache and does not need to disable the cache. (`DM-50044 <https://rubinobs.atlassian.net/browse/DM-50044>`_)
|
|
62
|
+
- Significantly sped up ``Butler.pruneDatasets`` by using parallelized artifact deletions. (`DM-50724 <https://rubinobs.atlassian.net/browse/DM-50724>`_)
|
|
63
|
+
- Modified trash emptying in datastore such that only the datasets to be removed as part of the original butler request are the ones that are trashed immediately. (`DM-50727 <https://rubinobs.atlassian.net/browse/DM-50727>`_)
|
|
64
|
+
- Modified CLI tooling to work with both click 8.1 and click 8.2. (`DM-50823 <https://rubinobs.atlassian.net/browse/DM-50823>`_)
|
|
65
|
+
- Fixed handling of ``FileDatastore.transfer_from()`` such that it now works with chained datastores. (`DM-50935 <https://rubinobs.atlassian.net/browse/DM-50935>`_)
|
|
66
|
+
- Reorganized ``Butler.removeRuns()`` to remove datasets in chunks to provide more feedback to the user and allow for restarting if the command fails for some reason. (`DM-50996 <https://rubinobs.atlassian.net/browse/DM-50996>`_)
|
|
67
|
+
- Added a ``fallback_instrument`` to ObsCore configurations.
|
|
68
|
+
This instrument is used when an ObsCore record is constructed from a dataset type that has no instrument defined. (`DM-51269 <https://rubinobs.atlassian.net/browse/DM-51269>`_)
|
|
69
|
+
- ``Butler.transfer_from()`` will now raise a `FileNotFoundError` while transferring files if a file listed in the database is not actually available on the filesystem. Previously, it would silently skip the file. (`DM-51302 <https://rubinobs.atlassian.net/browse/DM-51302>`_)
|
|
70
|
+
|
|
71
|
+
|
|
1
72
|
Butler v29.0.0 (2025-03-25)
|
|
2
73
|
===========================
|
|
3
74
|
|
|
@@ -77,7 +77,7 @@ zip-safe = true
|
|
|
77
77
|
license-files = ["COPYRIGHT", "LICENSE", "bsd_license.txt", "gpl-v3.0.txt"]
|
|
78
78
|
|
|
79
79
|
[tool.setuptools.package-data]
|
|
80
|
-
"lsst.daf.butler" = ["py.typed", "configs/*.yaml", "configs/*/*.yaml"]
|
|
80
|
+
"lsst.daf.butler" = ["py.typed", "configs/*.yaml", "configs/*/*.yaml", "tests/registry_data/*.yaml"]
|
|
81
81
|
|
|
82
82
|
[tool.setuptools.dynamic]
|
|
83
83
|
version = { attr = "lsst_versions.get_lsst_version" }
|
|
@@ -67,6 +67,7 @@ if TYPE_CHECKING:
|
|
|
67
67
|
from .._dataset_type import DatasetType
|
|
68
68
|
from .._storage_class import StorageClass
|
|
69
69
|
from ..datastores.file_datastore.retrieve_artifacts import ArtifactIndexInfo
|
|
70
|
+
from ..datastores.fileDatastoreClient import FileDatastoreGetPayload
|
|
70
71
|
from ..registry.interfaces import DatasetIdRef, DatastoreRegistryBridgeManager
|
|
71
72
|
from .record_data import DatastoreRecordData
|
|
72
73
|
from .stored_file_info import StoredDatastoreItemInfo
|
|
@@ -613,7 +614,7 @@ class Datastore(FileTransferSource, metaclass=ABCMeta):
|
|
|
613
614
|
"""
|
|
614
615
|
raise NotImplementedError("Must be implemented by subclass")
|
|
615
616
|
|
|
616
|
-
def prepare_get_for_external_client(self, ref: DatasetRef) ->
|
|
617
|
+
def prepare_get_for_external_client(self, ref: DatasetRef) -> FileDatastoreGetPayload | None:
|
|
617
618
|
"""Retrieve serializable data that can be used to execute a ``get()``.
|
|
618
619
|
|
|
619
620
|
Parameters
|
|
@@ -32,7 +32,7 @@ __all__ = ("SerializedStoredFileInfo", "StoredDatastoreItemInfo", "StoredFileInf
|
|
|
32
32
|
import inspect
|
|
33
33
|
from collections.abc import Iterable, Mapping
|
|
34
34
|
from dataclasses import dataclass
|
|
35
|
-
from typing import TYPE_CHECKING, Any
|
|
35
|
+
from typing import TYPE_CHECKING, Any, ClassVar
|
|
36
36
|
|
|
37
37
|
import pydantic
|
|
38
38
|
|
|
@@ -192,30 +192,44 @@ class StoredFileInfo(StoredDatastoreItemInfo):
|
|
|
192
192
|
The formatter to use for this dataset.
|
|
193
193
|
path : `str`
|
|
194
194
|
Path to the artifact associated with this dataset.
|
|
195
|
-
storageClass : `StorageClass`
|
|
196
|
-
The storage class associated with this dataset.
|
|
195
|
+
storageClass : `StorageClass` or `None`
|
|
196
|
+
The storage class associated with this dataset. If `None`,
|
|
197
|
+
``storage_class_name`` must be provided as a keyword argument.
|
|
197
198
|
component : `str` or `None`, optional
|
|
198
199
|
The component if disassembled.
|
|
199
200
|
checksum : `str` or `None`, optional
|
|
200
201
|
The checksum of the artifact.
|
|
201
202
|
file_size : `int`
|
|
202
203
|
The size of the file in bytes. -1 indicates the size is not known.
|
|
204
|
+
storage_class_name : `str`, optional
|
|
205
|
+
Name of the storage class. This may be passed instead of
|
|
206
|
+
``storageClass`` to defer loading storage class definitions (e.g. if a
|
|
207
|
+
butler configuration may not have been loaded yet). Note that
|
|
208
|
+
``storageClass=None`` must be passed explicitly (for backward
|
|
209
|
+
compatibility, it remains a positional argument with no default).
|
|
203
210
|
"""
|
|
204
211
|
|
|
205
|
-
storageClassFactory = StorageClassFactory()
|
|
212
|
+
storageClassFactory: ClassVar[StorageClassFactory] = StorageClassFactory()
|
|
206
213
|
|
|
207
214
|
def __init__(
|
|
208
215
|
self,
|
|
209
216
|
formatter: FormatterParameter,
|
|
210
217
|
path: str,
|
|
211
|
-
storageClass: StorageClass,
|
|
218
|
+
storageClass: StorageClass | None,
|
|
212
219
|
component: str | None,
|
|
213
220
|
checksum: str | None,
|
|
214
221
|
file_size: int,
|
|
222
|
+
*,
|
|
223
|
+
storage_class_name: str | None = None,
|
|
215
224
|
):
|
|
216
225
|
# Use these shenanigans to allow us to use a frozen dataclass
|
|
217
226
|
object.__setattr__(self, "path", path)
|
|
218
|
-
|
|
227
|
+
if storageClass is not None:
|
|
228
|
+
object.__setattr__(self, "storage_class_name", storageClass.name)
|
|
229
|
+
else:
|
|
230
|
+
if storage_class_name is None:
|
|
231
|
+
raise TypeError("At least one of 'storageClass' and 'storage_class_name' must be provided.")
|
|
232
|
+
object.__setattr__(self, "storage_class_name", storage_class_name)
|
|
219
233
|
object.__setattr__(self, "component", component)
|
|
220
234
|
object.__setattr__(self, "checksum", checksum)
|
|
221
235
|
object.__setattr__(self, "file_size", file_size)
|
|
@@ -238,8 +252,8 @@ class StoredFileInfo(StoredDatastoreItemInfo):
|
|
|
238
252
|
path: str
|
|
239
253
|
"""Path to dataset within Datastore."""
|
|
240
254
|
|
|
241
|
-
|
|
242
|
-
"""
|
|
255
|
+
storage_class_name: str
|
|
256
|
+
"""Name of the storage class associated with this dataset."""
|
|
243
257
|
|
|
244
258
|
component: str | None
|
|
245
259
|
"""Component associated with this file. Can be `None` if the file does
|
|
@@ -251,6 +265,11 @@ class StoredFileInfo(StoredDatastoreItemInfo):
|
|
|
251
265
|
file_size: int
|
|
252
266
|
"""Size of the serialized dataset in bytes."""
|
|
253
267
|
|
|
268
|
+
@property
|
|
269
|
+
def storageClass(self) -> StorageClass:
|
|
270
|
+
"""Storage class associated with this dataset."""
|
|
271
|
+
return self.storageClassFactory.getStorageClass(self.storage_class_name)
|
|
272
|
+
|
|
254
273
|
def rebase(self, ref: DatasetRef) -> StoredFileInfo:
|
|
255
274
|
"""Return a copy of the record suitable for a specified reference.
|
|
256
275
|
|
|
@@ -287,7 +306,7 @@ class StoredFileInfo(StoredDatastoreItemInfo):
|
|
|
287
306
|
return dict(
|
|
288
307
|
formatter=self.formatter,
|
|
289
308
|
path=self.path,
|
|
290
|
-
storage_class=self.
|
|
309
|
+
storage_class=self.storage_class_name,
|
|
291
310
|
component=component,
|
|
292
311
|
checksum=self.checksum,
|
|
293
312
|
file_size=self.file_size,
|
|
@@ -336,12 +355,12 @@ class StoredFileInfo(StoredDatastoreItemInfo):
|
|
|
336
355
|
The newly-constructed item corresponding to the record.
|
|
337
356
|
"""
|
|
338
357
|
# Convert name of StorageClass to instance
|
|
339
|
-
storageClass = cls.storageClassFactory.getStorageClass(record["storage_class"])
|
|
340
358
|
component = record["component"] if (record["component"] and record["component"] != NULLSTR) else None
|
|
341
359
|
info = cls(
|
|
342
360
|
formatter=record["formatter"],
|
|
343
361
|
path=record["path"],
|
|
344
|
-
storageClass=
|
|
362
|
+
storageClass=None,
|
|
363
|
+
storage_class_name=record["storage_class"],
|
|
345
364
|
component=component,
|
|
346
365
|
checksum=record["checksum"],
|
|
347
366
|
file_size=record["file_size"],
|
|
@@ -353,7 +372,7 @@ class StoredFileInfo(StoredDatastoreItemInfo):
|
|
|
353
372
|
return cls.from_record(dict(model))
|
|
354
373
|
|
|
355
374
|
def update(self, **kwargs: Any) -> StoredFileInfo:
|
|
356
|
-
new_args = {}
|
|
375
|
+
new_args: dict[str, Any] = {"storageClass": None} # so `storage_class_name` can be passed.
|
|
357
376
|
for k in self.__slots__:
|
|
358
377
|
if k in kwargs:
|
|
359
378
|
new_args[k] = kwargs.pop(k)
|
|
@@ -61,6 +61,8 @@ if TYPE_CHECKING:
|
|
|
61
61
|
from lsst.daf.butler.registry.interfaces import DatasetIdRef, DatastoreRegistryBridgeManager
|
|
62
62
|
from lsst.resources import ResourcePathExpression
|
|
63
63
|
|
|
64
|
+
from .fileDatastoreClient import FileDatastoreGetPayload
|
|
65
|
+
|
|
64
66
|
log = getLogger(__name__)
|
|
65
67
|
|
|
66
68
|
|
|
@@ -409,7 +411,7 @@ class ChainedDatastore(Datastore):
|
|
|
409
411
|
|
|
410
412
|
raise FileNotFoundError(f"Dataset {ref} could not be found in any of the datastores")
|
|
411
413
|
|
|
412
|
-
def prepare_get_for_external_client(self, ref: DatasetRef) ->
|
|
414
|
+
def prepare_get_for_external_client(self, ref: DatasetRef) -> FileDatastoreGetPayload | None:
|
|
413
415
|
datastore = self._get_matching_datastore(ref)
|
|
414
416
|
if datastore is None:
|
|
415
417
|
return None
|
|
@@ -1879,18 +1879,15 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
1879
1879
|
# Docstring inherited.
|
|
1880
1880
|
if not self.isWriteable():
|
|
1881
1881
|
raise TypeError("Butler is read-only.")
|
|
1882
|
-
if format is None:
|
|
1883
|
-
if filename is None:
|
|
1884
|
-
raise TypeError("At least one of 'filename' or 'format' must be provided.")
|
|
1885
|
-
else:
|
|
1886
|
-
_, format = os.path.splitext(filename) # type: ignore
|
|
1887
|
-
elif filename is None:
|
|
1882
|
+
if filename is None and format is not None:
|
|
1888
1883
|
filename = ResourcePath(f"export.{format}", forceAbsolute=False)
|
|
1889
1884
|
if directory is not None:
|
|
1890
1885
|
directory = ResourcePath(directory, forceDirectory=True)
|
|
1891
1886
|
# mypy doesn't think this will work but it does in python >= 3.10.
|
|
1892
1887
|
if isinstance(filename, ResourcePathExpression): # type: ignore
|
|
1893
1888
|
filename = ResourcePath(filename, forceAbsolute=False) # type: ignore
|
|
1889
|
+
if format is None:
|
|
1890
|
+
format = filename.getExtension()
|
|
1894
1891
|
if not filename.isabs() and directory is not None:
|
|
1895
1892
|
potential = directory.join(filename)
|
|
1896
1893
|
exists_in_cwd = filename.exists()
|
|
@@ -1914,6 +1911,8 @@ class DirectButler(Butler): # numpydoc ignore=PR02
|
|
|
1914
1911
|
raise FileNotFoundError(
|
|
1915
1912
|
f"Export file could not be found in {filename.abspath()} or {potential.abspath()}."
|
|
1916
1913
|
)
|
|
1914
|
+
elif format is None:
|
|
1915
|
+
format = ".yaml"
|
|
1917
1916
|
BackendClass: type[RepoImportBackend] = get_class_of(
|
|
1918
1917
|
self._config["repo_transfer_formats"][format]["import"]
|
|
1919
1918
|
)
|
|
@@ -353,7 +353,7 @@ class DirectQueryDriver(QueryDriver):
|
|
|
353
353
|
else:
|
|
354
354
|
dict_rows = [dict(zip(dimensions.required, values)) for values in rows]
|
|
355
355
|
from_clause: sqlalchemy.FromClause
|
|
356
|
-
if len(dict_rows) > self._constant_rows_limit:
|
|
356
|
+
if self.db.supports_temporary_tables and len(dict_rows) > self._constant_rows_limit:
|
|
357
357
|
from_clause = self._exit_stack.enter_context(self.db.temporary_table(table_spec))
|
|
358
358
|
self.db.insert(from_clause, *dict_rows)
|
|
359
359
|
else:
|
|
@@ -119,3 +119,24 @@ class RegistryConfig(ConfigSubset):
|
|
|
119
119
|
(`sqlalchemy.engine.url.URL`).
|
|
120
120
|
"""
|
|
121
121
|
return ConnectionStringFactory.fromConfig(self)
|
|
122
|
+
|
|
123
|
+
@property
|
|
124
|
+
def areTemporaryTablesAllowed(self) -> bool:
|
|
125
|
+
"""Return `True` if the database allows creating temporary tables for
|
|
126
|
+
read operations; `False` otherwise.
|
|
127
|
+
|
|
128
|
+
By default this is `True`, because there is a performance penalty
|
|
129
|
+
for some queries if temporary tables cannot be used.
|
|
130
|
+
|
|
131
|
+
This should be set to `False` when using a Postgres hot standby using
|
|
132
|
+
physical replication or an AlloyDB read pool, since these backends
|
|
133
|
+
do not support temporary tables.
|
|
134
|
+
"""
|
|
135
|
+
key = "temporary_tables"
|
|
136
|
+
value = self.get(key)
|
|
137
|
+
if value is None:
|
|
138
|
+
return True
|
|
139
|
+
elif isinstance(value, bool):
|
|
140
|
+
return value
|
|
141
|
+
|
|
142
|
+
raise ValueError(f"Unexpected value '{value}' for '{key}' in registry configuration")
|
|
@@ -65,6 +65,10 @@ class PostgresqlDatabase(Database):
|
|
|
65
65
|
writeable : `bool`, optional
|
|
66
66
|
If `True`, allow write operations on the database, including
|
|
67
67
|
``CREATE TABLE``.
|
|
68
|
+
allow_temporary_tables : `bool`, optional
|
|
69
|
+
If `True`, database operations will be allowed to use temporary tables.
|
|
70
|
+
If `False`, other SQL constructs will be used instead of temporary
|
|
71
|
+
tables when possible.
|
|
68
72
|
|
|
69
73
|
Notes
|
|
70
74
|
-----
|
|
@@ -85,6 +89,7 @@ class PostgresqlDatabase(Database):
|
|
|
85
89
|
origin: int,
|
|
86
90
|
namespace: str | None = None,
|
|
87
91
|
writeable: bool = True,
|
|
92
|
+
allow_temporary_tables: bool = True,
|
|
88
93
|
):
|
|
89
94
|
with engine.connect() as connection:
|
|
90
95
|
# `Any` to make mypy ignore the line below, can't use type: ignore
|
|
@@ -114,6 +119,7 @@ class PostgresqlDatabase(Database):
|
|
|
114
119
|
dbname=dsn.get("dbname"),
|
|
115
120
|
metadata=None,
|
|
116
121
|
pg_version=pg_version,
|
|
122
|
+
allow_temporary_tables=allow_temporary_tables,
|
|
117
123
|
)
|
|
118
124
|
|
|
119
125
|
def _init(
|
|
@@ -126,9 +132,16 @@ class PostgresqlDatabase(Database):
|
|
|
126
132
|
dbname: str,
|
|
127
133
|
metadata: DatabaseMetadata | None,
|
|
128
134
|
pg_version: tuple[int, int],
|
|
135
|
+
allow_temporary_tables: bool = True,
|
|
129
136
|
) -> None:
|
|
130
137
|
# Initialization logic shared between ``__init__`` and ``clone``.
|
|
131
|
-
super().__init__(
|
|
138
|
+
super().__init__(
|
|
139
|
+
origin=origin,
|
|
140
|
+
engine=engine,
|
|
141
|
+
namespace=namespace,
|
|
142
|
+
metadata=metadata,
|
|
143
|
+
allow_temporary_tables=allow_temporary_tables,
|
|
144
|
+
)
|
|
132
145
|
self._writeable = writeable
|
|
133
146
|
self.dbname = dbname
|
|
134
147
|
self._pg_version = pg_version
|
|
@@ -143,6 +156,7 @@ class PostgresqlDatabase(Database):
|
|
|
143
156
|
dbname=self.dbname,
|
|
144
157
|
metadata=self._metadata,
|
|
145
158
|
pg_version=self._pg_version,
|
|
159
|
+
allow_temporary_tables=self._allow_temporary_tables,
|
|
146
160
|
)
|
|
147
161
|
return clone
|
|
148
162
|
|
|
@@ -74,6 +74,11 @@ class SqliteDatabase(Database):
|
|
|
74
74
|
writeable : `bool`, optional
|
|
75
75
|
If `True`, allow write operations on the database, including
|
|
76
76
|
``CREATE TABLE``.
|
|
77
|
+
allow_temporary_tables : `bool`, optional
|
|
78
|
+
If `True`, database operations will be allowed to use temporary
|
|
79
|
+
tables.
|
|
80
|
+
If `False`, other SQL constructs will be used instead of temporary
|
|
81
|
+
tables when possible.
|
|
77
82
|
|
|
78
83
|
Notes
|
|
79
84
|
-----
|
|
@@ -90,6 +95,7 @@ class SqliteDatabase(Database):
|
|
|
90
95
|
origin: int,
|
|
91
96
|
namespace: str | None = None,
|
|
92
97
|
writeable: bool = True,
|
|
98
|
+
allow_temporary_tables: bool = True,
|
|
93
99
|
):
|
|
94
100
|
filename = _find_database_filename(engine, namespace)
|
|
95
101
|
self._init(
|
|
@@ -99,6 +105,7 @@ class SqliteDatabase(Database):
|
|
|
99
105
|
writeable=writeable,
|
|
100
106
|
filename=filename,
|
|
101
107
|
metadata=None,
|
|
108
|
+
allow_temporary_tables=allow_temporary_tables,
|
|
102
109
|
)
|
|
103
110
|
|
|
104
111
|
def _init(
|
|
@@ -110,9 +117,16 @@ class SqliteDatabase(Database):
|
|
|
110
117
|
writeable: bool = True,
|
|
111
118
|
filename: str | None,
|
|
112
119
|
metadata: DatabaseMetadata | None,
|
|
120
|
+
allow_temporary_tables: bool,
|
|
113
121
|
) -> None:
|
|
114
122
|
# Initialization logic shared between ``__init__`` and ``clone``.
|
|
115
|
-
super().__init__(
|
|
123
|
+
super().__init__(
|
|
124
|
+
origin=origin,
|
|
125
|
+
engine=engine,
|
|
126
|
+
namespace=namespace,
|
|
127
|
+
metadata=metadata,
|
|
128
|
+
allow_temporary_tables=allow_temporary_tables,
|
|
129
|
+
)
|
|
116
130
|
self._writeable = writeable
|
|
117
131
|
self.filename = filename
|
|
118
132
|
|
|
@@ -125,6 +139,7 @@ class SqliteDatabase(Database):
|
|
|
125
139
|
writeable=self._writeable,
|
|
126
140
|
filename=self.filename,
|
|
127
141
|
metadata=self._metadata,
|
|
142
|
+
allow_temporary_tables=self._allow_temporary_tables,
|
|
128
143
|
)
|
|
129
144
|
return clone
|
|
130
145
|
|
|
@@ -238,6 +238,10 @@ class Database(ABC):
|
|
|
238
238
|
Object representing the tables and other schema entities. If not
|
|
239
239
|
provided, will be generated during the next call to
|
|
240
240
|
``declareStaticTables``.
|
|
241
|
+
allow_temporary_tables : `bool`, optional
|
|
242
|
+
If `True`, database operations will be allowed to use temporary tables.
|
|
243
|
+
If `False`, other SQL constructs will be used instead of temporary
|
|
244
|
+
tables when possible.
|
|
241
245
|
|
|
242
246
|
Notes
|
|
243
247
|
-----
|
|
@@ -272,6 +276,7 @@ class Database(ABC):
|
|
|
272
276
|
engine: sqlalchemy.engine.Engine,
|
|
273
277
|
namespace: str | None = None,
|
|
274
278
|
metadata: DatabaseMetadata | None = None,
|
|
279
|
+
allow_temporary_tables: bool = True,
|
|
275
280
|
):
|
|
276
281
|
self.origin = origin
|
|
277
282
|
self.name_shrinker = NameShrinker(engine.dialect.max_identifier_length)
|
|
@@ -280,6 +285,7 @@ class Database(ABC):
|
|
|
280
285
|
self._session_connection: sqlalchemy.engine.Connection | None = None
|
|
281
286
|
self._temp_tables: set[str] = set()
|
|
282
287
|
self._metadata = metadata
|
|
288
|
+
self._allow_temporary_tables = allow_temporary_tables
|
|
283
289
|
|
|
284
290
|
def __repr__(self) -> str:
|
|
285
291
|
# Rather than try to reproduce all the parameters used to create
|
|
@@ -318,6 +324,7 @@ class Database(ABC):
|
|
|
318
324
|
origin: int,
|
|
319
325
|
namespace: str | None = None,
|
|
320
326
|
writeable: bool = True,
|
|
327
|
+
allow_temporary_tables: bool = True,
|
|
321
328
|
) -> Database:
|
|
322
329
|
"""Construct a database from a SQLAlchemy URI.
|
|
323
330
|
|
|
@@ -336,15 +343,22 @@ class Database(ABC):
|
|
|
336
343
|
writeable : `bool`, optional
|
|
337
344
|
If `True`, allow write operations on the database, including
|
|
338
345
|
``CREATE TABLE``.
|
|
346
|
+
allow_temporary_tables : `bool`, optional
|
|
347
|
+
If `True`, database operations will be allowed to use temporary
|
|
348
|
+
tables.
|
|
349
|
+
If `False`, other SQL constructs will be used instead of temporary
|
|
350
|
+
tables when possible.
|
|
339
351
|
|
|
340
352
|
Returns
|
|
341
353
|
-------
|
|
342
354
|
db : `Database`
|
|
343
355
|
A new `Database` instance.
|
|
344
356
|
"""
|
|
345
|
-
|
|
357
|
+
db = cls.fromEngine(
|
|
346
358
|
cls.makeEngine(uri, writeable=writeable), origin=origin, namespace=namespace, writeable=writeable
|
|
347
359
|
)
|
|
360
|
+
db._allow_temporary_tables = allow_temporary_tables
|
|
361
|
+
return db
|
|
348
362
|
|
|
349
363
|
@abstractmethod
|
|
350
364
|
def clone(self) -> Database:
|
|
@@ -539,6 +553,8 @@ class Database(ABC):
|
|
|
539
553
|
support the full range of expected read-only butler behavior.
|
|
540
554
|
"""
|
|
541
555
|
assert self._metadata is not None, "Static tables must be created before temporary tables"
|
|
556
|
+
if not self.supports_temporary_tables:
|
|
557
|
+
raise ReadOnlyDatabaseError("Creation of temporary tables is not supported by this database.")
|
|
542
558
|
with self._session() as connection:
|
|
543
559
|
table = self._make_temporary_table(connection, spec=spec, name=name)
|
|
544
560
|
self._temp_tables.add(table.key)
|
|
@@ -1954,6 +1970,10 @@ class Database(ABC):
|
|
|
1954
1970
|
"""
|
|
1955
1971
|
raise NotImplementedError()
|
|
1956
1972
|
|
|
1973
|
+
@property
|
|
1974
|
+
def supports_temporary_tables(self) -> bool:
|
|
1975
|
+
return self._allow_temporary_tables
|
|
1976
|
+
|
|
1957
1977
|
@abstractmethod
|
|
1958
1978
|
def apply_any_aggregate(self, column: sqlalchemy.ColumnElement[Any]) -> sqlalchemy.ColumnElement[Any]:
|
|
1959
1979
|
"""Wrap the given SQLAlchemy column in the ``ANY_VALUE`` aggregate
|
|
@@ -183,6 +183,11 @@ class ObsCoreConfig(pydantic.BaseModel):
|
|
|
183
183
|
dimension. Will be left unset if `None`. Can be dangerous to set this
|
|
184
184
|
in a repository containing data from multiple instruments."""
|
|
185
185
|
|
|
186
|
+
obs_publisher_did_fmt: str | None = None
|
|
187
|
+
"""Format string to generate an obs_publisher_did for a record. Assumes
|
|
188
|
+
that a single string is suitable for all results.
|
|
189
|
+
"""
|
|
190
|
+
|
|
186
191
|
|
|
187
192
|
class ConfigCollectionType(str, enum.Enum):
|
|
188
193
|
"""Enum class defining possible values for configuration attributes."""
|
|
@@ -197,6 +197,9 @@ class RecordFactory:
|
|
|
197
197
|
if dataset_config.datalink_url_fmt:
|
|
198
198
|
record["access_url"] = dataset_config.datalink_url_fmt.format(**fmt_kws)
|
|
199
199
|
|
|
200
|
+
if self.config.obs_publisher_did_fmt:
|
|
201
|
+
record["obs_publisher_did"] = self.config.obs_publisher_did_fmt.format(**fmt_kws)
|
|
202
|
+
|
|
200
203
|
extra_columns = {}
|
|
201
204
|
if self.config.extra_columns:
|
|
202
205
|
extra_columns.update(self.config.extra_columns)
|
|
@@ -187,7 +187,10 @@ class SqlRegistry:
|
|
|
187
187
|
|
|
188
188
|
DatabaseClass = config.getDatabaseClass()
|
|
189
189
|
database = DatabaseClass.fromUri(
|
|
190
|
-
config.connectionString,
|
|
190
|
+
config.connectionString,
|
|
191
|
+
origin=config.get("origin", 0),
|
|
192
|
+
namespace=config.get("namespace"),
|
|
193
|
+
allow_temporary_tables=config.areTemporaryTablesAllowed,
|
|
191
194
|
)
|
|
192
195
|
managerTypes = RegistryManagerTypes.fromConfig(config)
|
|
193
196
|
managers = managerTypes.makeRepo(database, dimensionConfig)
|
|
@@ -230,6 +233,7 @@ class SqlRegistry:
|
|
|
230
233
|
origin=config.get("origin", 0),
|
|
231
234
|
namespace=config.get("namespace"),
|
|
232
235
|
writeable=writeable,
|
|
236
|
+
allow_temporary_tables=config.areTemporaryTablesAllowed,
|
|
233
237
|
)
|
|
234
238
|
managerTypes = RegistryManagerTypes.fromConfig(config)
|
|
235
239
|
with database.session():
|