DimensionRecordStorage

class lsst.daf.butler.registry.interfaces.DimensionRecordStorage

Bases: abc.ABC

An abstract base class that represents a way of storing the records associated with a single DimensionElement.

Concrete DimensionRecordStorage instances should generally be constructed via a call to setupDimensionStorage, which selects the appropriate subclass for each element according to its configuration.

All DimensionRecordStorage methods are pure abstract, even though in some cases a reasonable default implementation might be possible, in order to better guarantee all methods are correctly overridden. All of these potentially-defaultable implementations are extremely trivial, so asking subclasses to provide them is not a significant burden.

Attributes Summary

element The element whose records this instance holds (DimensionElement).

Methods Summary

clearCaches() Clear any in-memory caches held by the storage instance.
fetch(dataId) Retrieve a record from storage.
getDefaultImplementation(element, ignoreCached) Return the default DimensionRecordStorage implementation for the given DimensionElement.
initialize(db, element, *, context) Construct an instance of this class using a standardized interface.
insert(*records) Insert one or more records into storage.
join(builder, *, regions, …) Add the dimension element’s logical table to a query under construction.
sync(record) Synchronize a record with the database, inserting it only if it does not exist and comparing values if it does.

Attributes Documentation

element

The element whose records this instance holds (DimensionElement).

Methods Documentation

clearCaches() → None

Clear any in-memory caches held by the storage instance.

This is called by Registry when transactions are rolled back, to avoid in-memory caches from ever containing records that are not present in persistent storage.

fetch(dataId: DataId) → Optional[DimensionRecord]

Retrieve a record from storage.

Parameters:
dataId : DataId

A data ID that identifies the record to be retrieved. This may be an informal data ID dict or a validated DataCoordinate.

Returns:
record : DimensionRecord or None

A record retrieved from storage, or None if there is no such record.

static getDefaultImplementation(element: DimensionElement, ignoreCached: bool = False) → Type[DimensionRecordStorage]

Return the default DimensionRecordStorage implementation for the given DimensionElement.

Parameters:
element : DimensionElement

The element whose properties should be examined to determine the appropriate default implementation class.

ignoreCached : bool, optional

If True, ignore DimensionElement.cached and always return the storage implementation that would be used without caching.

Returns:
cls : type

A concrete subclass of DimensionRecordStorage.

Notes

At present, these defaults are always used, but we may add support for explicitly setting the class to use in configuration in the future.

classmethod initialize(db: Database, element: DimensionElement, *, context: Optional[StaticTablesContext] = None) → DimensionRecordStorage

Construct an instance of this class using a standardized interface.

Parameters:
db : Database

Interface to the underlying database engine and namespace.

element : DimensionElement

Dimension element the new instance will manage records for.

context : StaticTablesContext, optional

If provided, an object to use to create any new tables. If not provided, db.ensureTableExists should be used instead.

Returns:
storage : DimensionRecordStorage

A new DimensionRecordStorage subclass instance.

insert(*records) → None

Insert one or more records into storage.

Parameters:
records

One or more instances of the DimensionRecord subclass for the element this storage is associated with.

Raises:
TypeError

Raised if the element does not support record insertion.

sqlalchemy.exc.IntegrityError

Raised if one or more records violate database integrity constraints.

Notes

As insert is expected to be called only by a Registry, we rely on Registry to provide transactionality, both by using a SQLALchemy connection shared with the Registry and by relying on it to call clearCaches when rolling back transactions.

join(builder: QueryBuilder, *, regions: Optional[NamedKeyDict[DimensionElement, sqlalchemy.sql.ColumnElement]] = None, timespans: Optional[NamedKeyDict[DimensionElement, Timespan[sqlalchemy.sql.ColumnElement]]] = None) → sqlalchemy.sql.FromClause

Add the dimension element’s logical table to a query under construction.

This is a visitor pattern interface that is expected to be called only by QueryBuilder.joinDimensionElement.

Parameters:
builder : QueryBuilder

Builder for the query that should contain this element.

regions : NamedKeyDict, optional

A mapping from DimensionElement to a SQLAlchemy column containing the region for that element, which should be updated to include a region column for this element if one exists. If None, self.element is not being included in the query via a spatial join.

timespan : NamedKeyDict, optional

A mapping from DimensionElement to a Timespan of SQLALchemy columns containing the timespan for that element, which should be updated to include timespan columns for this element if they exist. If None, self.element is not being included in the query via a temporal join.

Returns:
fromClause : sqlalchemy.sql.FromClause

Table or clause for the element which is joined.

Notes

Elements are only included in queries via spatial and/or temporal joins when necessary to connect them to other elements in the query, so regions and timespans cannot be assumed to be not None just because an element has a region or timespan.

sync(record: DimensionRecord) → bool

Synchronize a record with the database, inserting it only if it does not exist and comparing values if it does.

Parameters:
record : DimensionRecord.

An instance of the DimensionRecord subclass for the element this storage is associated with.

Returns:
inserted : bool

True if a new row was inserted, False otherwise.

Raises:
DatabaseConflictError

Raised if the record exists in the database (according to primary key lookup) but is inconsistent with the given one.

TypeError

Raised if the element does not support record synchronization.

sqlalchemy.exc.IntegrityError

Raised if one or more records violate database integrity constraints.

Notes

This method cannot be called within transactions, as it needs to be able to perform its own transaction to be concurrent.