Query¶
- 
class lsst.daf.butler.registry.queries.Query(*, graph: lsst.daf.butler.core.dimensions._graph.DimensionGraph, whereRegion: Optional[lsst.sphgeom._sphgeom.Region, None], backend: lsst.daf.butler.registry.queries._query_backend.QueryBackend, doomed_by: Iterable[str] = ())¶
- Bases: - abc.ABC- An abstract base class for queries that return some combination of - DatasetRefand- DataCoordinateobjects.- Parameters: - graph : DimensionGraph
- Object describing the dimensions included in the query. 
- whereRegion : lsst.sphgeom.Region, optional
- Region that all region columns in all returned rows must overlap. 
- backend : QueryBackend
- Backend object that represents the - Registryimplementation.
- doomed_by : Iterable[str], optional
- A list of messages (appropriate for e.g. logging or exceptions) that explain why the query is known to return no results even before it is executed. Queries with a non-empty list will never be executed. 
 - Notes - The - Queryhierarchy abstracts over the database/SQL representation of a particular set of data IDs or datasets. It is expected to be used as a backend for other objects that provide more natural interfaces for one or both of these, not as part of a public interface to query results.- Attributes Summary - datasetType- The - DatasetTypeof datasets returned by this query, or- Noneif there are no dataset results (- DatasetTypeor- None).- spatial- An iterator over the dimension element columns used in post-query filtering of spatial overlaps ( - Iterator[- DimensionElement]).- sql- A SQLAlchemy object representing the full query ( - sqlalchemy.sql.FromClauseor- None).- Methods Summary - any(db, *, execute, exact)- Test whether this query returns any results. - count(db, *, exact)- Count the number of rows this query would return. - explain_no_results(db, *, followup)- Return human-readable messages that may help explain why the query yields no results. - extractDataId(row, *, graph, records, …)- Extract a data ID from a result row. - extractDatasetRef(row, dataId, records, …)- Extract a - DatasetReffrom a result row.- extractDimensionsTuple(row, dimensions)- Extract a tuple of data ID values from a result row. - getDatasetColumns()- Return the columns for the datasets returned by this query. - getDimensionColumn(name)- Return the query column that contains the primary key value for the dimension with the given name. - getRegionColumn(name)- Return a region column for one of the dimension elements iterated over by - spatial.- isUnique()- Return - Trueif this query’s rows are guaranteed to be unique, and- Falseotherwise.- makeBuilder(summary)- Return a - QueryBuilderthat can be used to construct a new- Querythat is joined to (and hence constrained by) this one.- materialize(db)- Execute this query and insert its results into a temporary table. - rows(db)- Execute the query and yield result rows, applying - predicate.- subset(*, graph, None] = None, datasets, unique)- Return a new - Querywhose columns and/or rows are (mostly) subset of this one’s.- Attributes Documentation - 
datasetType¶
- The - DatasetTypeof datasets returned by this query, or- Noneif there are no dataset results (- DatasetTypeor- None).
 - 
spatial¶
- An iterator over the dimension element columns used in post-query filtering of spatial overlaps ( - Iterator[- DimensionElement]).- Notes - This property is intended primarily as a hook for subclasses to implement and the ABC to call in order to provide higher-level functionality; code that uses - Queryobjects (but does not implement one) should usually not have to access this property.
 - 
sql¶
- A SQLAlchemy object representing the full query ( - sqlalchemy.sql.FromClauseor- None).- This is - Nonein the special case where the query has no columns, and only one logical row.
 - Methods Documentation - 
any(db: lsst.daf.butler.registry.interfaces._database.Database, *, execute: bool = True, exact: bool = True) → bool¶
- Test whether this query returns any results. - Parameters: - db : Database
- Object managing the database connection. 
- execute : bool, optional
- If - True, execute at least a- LIMIT 1query if it cannot be determined prior to execution that the query would return no rows.
- exact : bool, optional
- If - True, run the full query and perform post-query filtering if needed, until at least one result row is found. If- False, the returned result does not account for post-query filtering, and hence may be- Trueeven when all result rows would be filtered out.
 - Returns: 
- db : 
 - 
count(db: lsst.daf.butler.registry.interfaces._database.Database, *, exact: bool = True) → int¶
- Count the number of rows this query would return. - Parameters: - Returns: - count : int
- The number of rows the query would return, or an upper bound if - exact=False.
 - Notes - This counts the number of rows returned, not the number of unique rows returned, so even with - exact=Trueit may provide only an upper bound on the number of deduplicated result rows.
- count : 
 - 
explain_no_results(db: lsst.daf.butler.registry.interfaces._database.Database, *, followup: bool = True) → Iterator[str]¶
- Return human-readable messages that may help explain why the query yields no results. - Parameters: - Returns: - messages : Iterator[str]
- String messages that describe reasons the query might not yield any results. 
 - Notes - Messages related to post-query filtering are only available if - rows,- any, or- countwas already called with the same region (with- exact=Truefor the latter two).
- messages : 
 - 
extractDataId(row: Optional[sqlalchemy.engine.RowProxy], *, graph: Optional[DimensionGraph] = None, records: Optional[Mapping[str, Mapping[tuple, DimensionRecord]]] = None) → DataCoordinate¶
- Extract a data ID from a result row. - Parameters: - row : sqlalchemy.engine.RowProxyorNone
- A result row from a SQLAlchemy SELECT query, or - Noneto indicate the row from an- EmptyQuery.
- graph : DimensionGraph, optional
- The dimensions the returned data ID should identify. If not provided, this will be all dimensions in - QuerySummary.requested.
- records : Mapping[str,Mapping[tuple,DimensionRecord] ]
- Nested mapping containing records to attach to the returned - DataCoordinate, for which- hasRecordswill return- True. If provided, outer keys must include all dimension element names in- graph, and inner keys should be tuples of dimension primary key values in the same order as- element.graph.required. If not provided,- DataCoordinate.hasRecordswill return- Falseon the returned object.
 - Returns: - dataId : DataCoordinate
- A data ID that identifies all required and implied dimensions. If - records is not None, this is have- hasRecords()return- True.
 
- row : 
 - 
extractDatasetRef(row: sqlalchemy.engine.RowProxy, dataId: Optional[DataCoordinate] = None, records: Optional[Mapping[str, Mapping[tuple, DimensionRecord]]] = None) → DatasetRef¶
- Extract a - DatasetReffrom a result row.- Parameters: - row : sqlalchemy.engine.RowProxy
- A result row from a SQLAlchemy SELECT query. 
- dataId : DataCoordinate
- Data ID to attach to the - DatasetRef. A minimal (i.e. base class)- DataCoordinateis constructed from- rowif- None.
- records : Mapping[str,Mapping[tuple,DimensionRecord] ]
- Records to use to return an - ExpandedDataCoordinate. If provided, outer keys must include all dimension element names in- graph, and inner keys should be tuples of dimension primary key values in the same order as- element.graph.required.
 - Returns: - ref : DatasetRef
- Reference to the dataset; guaranteed to have - DatasetRef.idnot- None.
 
- row : 
 - 
extractDimensionsTuple(row: Optional[sqlalchemy.engine.RowProxy], dimensions: Iterable[Dimension]) → tuple¶
- Extract a tuple of data ID values from a result row. - Parameters: - Returns: - values : tuple
- A tuple of dimension primary key values. 
 
- values : 
 - 
getDatasetColumns() → Optional[lsst.daf.butler.registry.queries._structs.DatasetQueryColumns, None]¶
- Return the columns for the datasets returned by this query. - Returns: - columns : DatasetQueryColumnsorNone
- Struct containing SQLAlchemy representations of the result columns for a dataset. 
 - Notes - This method is intended primarily as a hook for subclasses to implement and the ABC to call in order to provide higher-level functionality; code that uses - Queryobjects (but does not implement one) should usually not have to call this method.
- columns : 
 - 
getDimensionColumn(name: str) → sqlalchemy.sql.elements.ColumnElement¶
- Return the query column that contains the primary key value for the dimension with the given name. - Parameters: - name : str
- Name of the dimension. 
 - Returns: - column : sqlalchemy.sql.ColumnElement.
- SQLAlchemy object representing a column in the query. 
 - Notes - This method is intended primarily as a hook for subclasses to implement and the ABC to call in order to provide higher-level functionality; code that uses - Queryobjects (but does not implement one) should usually not have to call this method.
- name : 
 - 
getRegionColumn(name: str) → sqlalchemy.sql.elements.ColumnElement¶
- Return a region column for one of the dimension elements iterated over by - spatial.- Parameters: - name : str
- Name of the element. 
 - Returns: - column : sqlalchemy.sql.ColumnElement
- SQLAlchemy representing a result column in the query. 
 - Notes - This method is intended primarily as a hook for subclasses to implement and the ABC to call in order to provide higher-level functionality; code that uses - Queryobjects (but does not implement one) should usually not have to call this method.
- name : 
 - 
isUnique() → bool¶
- Return - Trueif this query’s rows are guaranteed to be unique, and- Falseotherwise.- If this query has dataset results ( - datasetTypeis not- None), uniqueness applies to the- DatasetRefinstances returned by- extractDatasetReffrom the result of- rows. If it does not have dataset results, uniqueness applies to the- DataCoordinateinstances returned by- extractDataId.
 - 
makeBuilder(summary: Optional[QuerySummary] = None) → QueryBuilder¶
- Return a - QueryBuilderthat can be used to construct a new- Querythat is joined to (and hence constrained by) this one.- Parameters: - summary : QuerySummary, optional
- A - QuerySummaryinstance that specifies the dimensions and any additional constraints to include in the new query being constructed, or- Noneto use the dimensions of- selfwith no additional constraints.
 
- summary : 
 - 
materialize(db: lsst.daf.butler.registry.interfaces._database.Database) → ContextManager[lsst.daf.butler.registry.queries._query.Query]¶
- Execute this query and insert its results into a temporary table. - Parameters: - db : Database
- Database engine to execute the query against. 
 - Returns: - context : typing.ContextManager[MaterializedQuery]
- A context manager that ensures the temporary table is created and populated in - __enter__(returning a- MaterializedQueryobject backed by that table), and dropped in- __exit__. If- selfis already a- MaterializedQuery,- __enter__may just return- selfand- __exit__may do nothing (reflecting the fact that an outer context manager should already take care of everything else).
 
- db : 
 - 
rows(db: Database) → Iterator[Optional[sqlalchemy.engine.RowProxy]]¶
- Execute the query and yield result rows, applying - predicate.- Parameters: - db : Database
- Object managing the database connection. 
 - Yields: 
- db : 
 - 
subset(*, graph: Optional[lsst.daf.butler.core.dimensions._graph.DimensionGraph, None] = None, datasets: bool = True, unique: bool = False) → lsst.daf.butler.registry.queries._query.Query¶
- Return a new - Querywhose columns and/or rows are (mostly) subset of this one’s.- Parameters: - graph : DimensionGraph, optional
- Dimensions to include in the new - Querybeing constructed. If- None(default),- self.graphis used.
- datasets : bool, optional
- Whether the new - Queryshould include dataset results. Defaults to- True, but is ignored if- selfdoes not include dataset results.
- unique : bool, optional
- Whether the new - Queryshould guarantee unique results (this may come with a performance penalty).
 - Returns: - query : Query
- A query object corresponding to the given inputs. May be - selfif no changes were requested.
 - Notes - The way spatial overlaps are handled at present makes it impossible to fully guarantee in general that the new query’s rows are a subset of this one’s while also returning unique rows. That’s because the database is only capable of performing approximate, conservative overlaps via the common skypix system; we defer actual region overlap operations to per-result-row Python logic. But including the region columns necessary to do that postprocessing in the query makes it impossible to do a SELECT DISTINCT on the user-visible dimensions of the query. For example, consider starting with a query with dimensions (instrument, skymap, visit, tract). That involves a spatial join between visit and tract, and we include the region columns from both tables in the results in order to only actually yield result rows (see - predicateand- rows) where the regions in those two columns overlap. If the user then wants to subset to just (skymap, tract) with unique results, we have two unpalatable options:- we can do a SELECT DISTINCT with just the skymap and tract columns in the SELECT clause, dropping all detailed overlap information and including some tracts that did not actually overlap any of the visits in the original query (but were regarded as _possibly_ overlapping via the coarser, common-skypix relationships);
- we can include the tract and visit region columns in the query, and continue to filter out the non-overlapping pairs, but completely disregard the user’s request for unique tracts.
 - This interface specifies that implementations must do the former, as that’s what makes things efficient in our most important use case ( - QuantumGraphgeneration in- pipe_base). We may be able to improve this situation in the future by putting exact overlap information in the database, either by using built-in (but engine-specific) spatial database functionality or (more likely) switching to a scheme in which pairwise dimension spatial relationships are explicitly precomputed (for e.g. combinations of instruments and skymaps).
- graph : 
 
- graph :