Skip to content

Commit

Permalink
Use predicates in dataId rewrite queries rather than where strings
Browse files Browse the repository at this point in the history
It's more efficient to be explicit about the query being requested
than to ask the query system to first try to parse the WHERE
strings that are created programmatically.
  • Loading branch information
timj committed Oct 11, 2024
1 parent d59d45d commit b876e90
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions python/lsst/daf/butler/direct_butler/_direct_butler.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import warnings
from collections import Counter, defaultdict
from collections.abc import Iterable, Iterator, MutableMapping, Sequence
from operator import attrgetter
from types import EllipsisType
from typing import TYPE_CHECKING, Any, ClassVar, TextIO, cast

Expand Down Expand Up @@ -708,21 +709,22 @@ def _rewrite_data_id(
for k, v in newDataId.items()
if k in self.dimensions[dimensionName].minimal_group.names
}
# Build up a WHERE expression
bind = dict(values.items())
where = " AND ".join(f"{dimensionName}.{k} = {k}" for k in bind)

# Hopefully we get a single record that matches
records = set(
self.query_dimension_records(
dimensionName,
data_id=filtered_data_id,
where=where,
bind=bind,
explain=False,
**kwargs,
)
)
def _get_attr(obj: Any, attr: str) -> Any:
# Used to implement x.exposure.seq_num when given
# x and "exposure.seq_num".
f = attrgetter(attr)
return f(obj)

with self.query() as q:
x = q.expression_factory
# Build up a WHERE expression.
predicates = tuple(_get_attr(x, f"{dimensionName}.{k}") == v for k, v in values.items())
extra_args: dict[str, Any] = {} # For mypy.
extra_args.update(filtered_data_id)
extra_args.update(kwargs)
q = q.where(x.all(*predicates), **extra_args)
records = set(q.dimension_records(dimensionName))

if len(records) != 1:
if len(records) > 1:
Expand Down

0 comments on commit b876e90

Please sign in to comment.