MCPcopy Create free account
hub / github.com/Flagsmith/flagsmith / ResultsQueryBuilder

Class ResultsQueryBuilder

api/experimentation/results_query.py:116–174  ·  view source on GitHub ↗

Assembles and decodes the experimentation results ClickHouse query.

Source from the content-addressed store, hash-verified

114
115
116class ResultsQueryBuilder:
117 """Assembles and decodes the experimentation results ClickHouse query."""
118
119 def __init__(self, specs: Sequence[MetricSpec]) -> None:
120 self._slots = [_MetricSlot(spec, i) for i, spec in enumerate(specs)]
121
122 def build_query(self) -> str:
123 if not self._slots:
124 return _EXPOSURES_COUNT_ONLY_QUERY
125
126 unit_selects = ",\n ".join(s.unit_select() for s in self._slots)
127 outer_selects = ",\n ".join(s.outer_select() for s in self._slots)
128
129 return (
130 _EXPOSURES_CTE
131 + f""",
132unit_values AS (
133 SELECT
134 e.variant AS variant,
135 {unit_selects}
136 FROM exposures AS e
137{_METRIC_JOIN}
138 WHERE e.quarantined = 0
139 GROUP BY e.identifier, e.variant
140)
141SELECT variant, count() AS n,
142 {outer_selects}
143FROM unit_values
144GROUP BY variant"""
145 )
146
147 def add_metric_params(self, params: dict[str, object]) -> None:
148 """Add per-metric query parameters into an existing params dict."""
149 if not self._slots:
150 return
151 params["metric_events"] = [s.spec.event for s in self._slots]
152 for slot in self._slots:
153 params[f"metric_{slot.index}_event"] = slot.spec.event
154
155 def decode_rows(
156 self, rows: list[Any], column_names: Sequence[str]
157 ) -> tuple[dict[str, int], dict[int, dict[str, VariantStats]]]:
158 """Decode raw ClickHouse rows into exposure counts and per-metric stats.
159
160 Columns are located by name, so a missing one raises KeyError rather than
161 silently reading a neighbour's value.
162 """
163 index = {name: position for position, name in enumerate(column_names)}
164 exposure_counts: dict[str, int] = {}
165 metric_stats: dict[int, dict[str, VariantStats]] = {
166 slot.spec.metric_id: {} for slot in self._slots
167 }
168 for row in rows:
169 variant = str(row[index["variant"]])
170 n = int(row[index["n"]])
171 exposure_counts[variant] = n
172 for slot in self._slots:
173 metric_stats[slot.spec.metric_id][variant] = slot.decode(n, row, index)

Callers 1

get_metric_variant_statsFunction · 0.90

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…