ftmq.Query
See the query guide.
A query over FtM entities: a filter tree of M / P / G / C nodes.
Examples:
from ftmq import Query, M, P, G
q = Query().where(M(schema="Person"), P(name__ilike="jane%"))
q = q.where(G(countries="de") | G(countries="at"))
q = q.order_by(P("name"))[:10]
Source code in ftmq/query/main.py
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 | |
dataset_names
property
The dataset names any filter leaf refers to, ignoring polarity.
limit
property
The limit, inferred from the slice.
offset
property
The offset, inferred from the slice (0 for q[:10]).
schemata_names
property
The schema names any filter leaf refers to, ignoring polarity.
A schemata (is-a) leaf expands to its non-abstract descendants.
__bool__()
Whether anything is set: filter, aggregation, projection, sort or slice.
Examples:
__getitem__(value)
Slice like a list; no negative values or steps.
Examples:
Returns:
| Type | Description |
|---|---|
Self
|
The updated |
Source code in ftmq/query/main.py
__hash__()
aggregate(*nodes)
Add aggregation projections.
Example
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*nodes
|
A
|
|
()
|
Returns:
| Type | Description |
|---|---|
Self
|
The updated |
Source code in ftmq/query/main.py
apply(entity)
apply_iter(entities)
Filter, sort, slice, aggregate and project a stream of entities.
Aggregation results are collected into self.aggregator.
Example
Yields:
| Type | Description |
|---|---|
EntityProxies
|
The matching entities. |
Source code in ftmq/query/main.py
compile(source=None)
Compile to a SQLAlchemy Select of statements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
'SqlSource | None'
|
The |
None
|
Returns:
| Type | Description |
|---|---|
'Select[Any]'
|
The statements |
Source code in ftmq/query/main.py
facet_size(ref, size)
Set how many (top) buckets a facet returns.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref
|
Ref
|
A facet of the query, e.g. |
required |
size
|
int
|
The number of buckets (default 20). |
required |
Returns:
| Type | Description |
|---|---|
Self
|
The updated |
Source code in ftmq/query/main.py
from_dict(data)
classmethod
Rebuild a Query from its to_dict output.
Source code in ftmq/query/main.py
from_params(args)
classmethod
Build a Query from an Aleph-style param dict / MultiDict.
Source code in ftmq/query/main.py
from_rql(value)
classmethod
Build a Query from an RQL string.
Carries arbitrary & | ~ nesting, aggregations and the projection.
Source code in ftmq/query/main.py
from_string(value)
classmethod
get_aggregator()
Build a fresh in-memory aggregator for the query's aggregations.
Returns:
| Type | Description |
|---|---|
Aggregator
|
The |
Source code in ftmq/query/main.py
get_facet_size(ref)
order_by(ref, *, ascending=True)
Sort by a single property: order_by(P("date"), ascending=False).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref
|
Ref
|
The property reference; only properties are sortable. |
required |
ascending
|
bool
|
Ascending or descending. |
True
|
Returns:
| Type | Description |
|---|---|
Self
|
The updated |
Source code in ftmq/query/main.py
order_facets(*, ascending=False, **func)
Rank facet buckets by a grouped metric: order_facets(sum=P("amountEur")).
Descending by default; also decides which buckets the facet size keeps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ascending
|
bool
|
Rank the smallest values first. |
False
|
**func
|
Ref
|
Exactly one |
{}
|
Returns:
| Type | Description |
|---|---|
Self
|
The updated |
Source code in ftmq/query/main.py
select(*refs)
Restrict which properties the matching entities are read with.
A projection, not a filter: it never changes which entities match. An entity holding none of the selected properties still comes back; caption and edges of a projected entity may be incomplete.
Example
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*refs
|
Ref
|
The |
()
|
Returns:
| Type | Description |
|---|---|
Self
|
The updated |
Raises:
| Type | Description |
|---|---|
QueryError
|
For a ref of any other family. |
Source code in ftmq/query/main.py
to_dict()
Serialize to a lossless nested dict.
Example
Source code in ftmq/query/main.py
to_params()
Serialize to an Aleph-style param dict.
Keys: filter: / exclude: / empty:, the aggregation keys (metric:,
facet, facet_sort, facet_size:), select, sort, limit, offset.
Raises:
| Type | Description |
|---|---|
QueryError
|
For a query outside the flat Aleph subset (cross-field OR, negated groups). |
Source code in ftmq/query/main.py
to_rql()
Serialize to an RQL string.
The only string surface preserving arbitrary & | ~ nesting; carries
aggregations and the projection, but no sort or slice.
Raises:
| Type | Description |
|---|---|
QueryError
|
For a comparator with no RQL equivalent ( |
Source code in ftmq/query/main.py
to_string()
where(*nodes)
AND nodes into the filter tree.
Example
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*nodes
|
Expr
|
|
()
|
Returns:
| Type | Description |
|---|---|
Self
|
The updated |
Source code in ftmq/query/main.py
Query nodes
Filter nodes M (meta), P (property), G (property-type group) and C (context), plus the aggregation node A.
Bases: _FamilyExpr
Meta fields (dataset, schema, schemata, id, ...): M(schema="Person")
as a condition, M("dataset") as a reference.
Source code in ftmq/query/nodes.py
Bases: _FamilyExpr
A specific FtM property: P(name="Jane", amountEur__gte=1000) as a
condition, P("amountEur") as a reference.
Source code in ftmq/query/nodes.py
An aggregation projection node: A(sum=P("amountEur"), by=P("beneficiary")).
Each keyword is a function (min, max, sum, avg, count) over one or
more refs; by= groups by one or more refs. It does not compose with
& | ~; pass it to Query.aggregate.
Examples:
A(sum=P("amountEur"), by=P("beneficiary"))
A(count=M("id"), by=[G("countries"), Year()])
A(sum=[P("amountEur"), P("amount")])
Source code in ftmq/query/aggregations.py
Expression tree
A boolean node: an AND / OR connector, an optional negation and children.
Children are Expr nodes or Leaf conditions,
canonicalized on construction: non-negated sub-groups of the same connector
are spliced in, duplicates dropped.
Source code in ftmq/query/nodes.py
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | |
apply(entity)
Evaluate the tree against an entity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity
|
EntityProxy
|
The entity to test. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
Whether the entity matches. |
Source code in ftmq/query/nodes.py
from_dict(data)
classmethod
Rebuild a tree from its to_dict form.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
dict[str, Any]
|
The nested mapping to deserialize. |
required |
Returns:
| Type | Description |
|---|---|
'Expr'
|
The reconstructed expression. |
Source code in ftmq/query/nodes.py
iter_leaves(cls=None)
Yield the tree's leaf conditions, depth-first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
cls
|
type | None
|
Optionally restrict to leaves of this class. |
None
|
Yields:
| Type | Description |
|---|---|
Leaf
|
Each matching leaf. |
Source code in ftmq/query/nodes.py
to_dict()
Serialize the tree to a nested dict, children in canonical order.
Structurally equal trees serialize, and hash, identically.
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
A |
Source code in ftmq/query/nodes.py
Combine a series of nodes with a single connector, skipping empties.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*nodes
|
Expr
|
The nodes to combine. |
()
|
connector
|
str
|
|
AND
|
Returns:
| Type | Description |
|---|---|
Expr | None
|
The combined expression, or |
Source code in ftmq/query/nodes.py
Field references
A field without a value, as used by aggregations, sorting and select: a family constructor called with a bare field name (P("amountEur")).
Field references: a leaf without a value.
A Ref names where to read (a property, a property-type
group, a meta or context column), reads its values off an entity and has one wire
spelling (Ref.wire /
ref_from_wire):
Query().where(P(amountEur__gte=1000)) # a leaf: ref + comparator + value
Query().aggregate(A(sum=P("amountEur"))) # an aggregation: just the ref
CanonicalIdRef
ContextRef
Bases: Ref
A context / storage column: origin, plus backend-specific columns
such as fragment, first_seen or bucket.
Source code in ftmq/query/refs.py
DatasetRef
Bases: MetaRef
The dataset an entity was observed in.
Source code in ftmq/query/refs.py
EntityIdRef
GroupRef
Bases: Ref
A followthemoney property-type group (the prop_type column):
names, dates, countries, entities, ...
Source code in ftmq/query/refs.py
IdRef
Bases: MetaRef
The entity id, not the referent ids in the value of a prop = "id" row.
Source code in ftmq/query/refs.py
MetaRef
PropRef
Bases: Ref
One followthemoney property (the prop column).
Source code in ftmq/query/refs.py
Ref
A reference to one field of one family.
Built via the M / P / G / C constructors called with a field name, or
Year(); subclasses set family / key and implement values().
Source code in ftmq/query/refs.py
is_numeric
property
Whether the values are read as numbers, not strings.
wire
property
The spelling on every string surface (params, rql, dict keys, CLI).
row_value(statement)
selects(prop)
SchemaRef
YearRef
Bases: Ref
The year of any date-typed value: derived from the dates group.
Source code in ftmq/query/refs.py
Year()
make_meta_ref(key)
Build a meta ref (the M family) by field name.
ref_from_wire(value)
Resolve a wire spelling into a ref, for every string surface.
properties.<name>, group.<name> and context.<name> name their family; a
meta field (id, entity_id, canonical_id, dataset, schema) and year
are bare.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
str
|
E.g. |
required |
Returns:
| Type | Description |
|---|---|
Ref
|
The resolved ref. |
Raises:
| Type | Description |
|---|---|
QueryError
|
If the spelling matches no field. |
Source code in ftmq/query/refs.py
Leaves
Leaf conditions, one family per statement-table column they target:
M(meta):dataset,schema(exact),schemata(is-a),id/entity_id/canonical_id.P: a followthemoney property (thepropcolumn).G: a property-type group (theprop_typecolumn, keyed byregistry.groups).C: a context / storage column such asorigin,fragmentorfirst_seen.
CanonicalIdLeaf
ContextLeaf
Bases: RefLeaf
A context / storage column (origin, fragment, first_seen, ...).
In memory it reads the column off the entity's statements, else
entity.context; in SQL the same-named statement-table column. An entity
without the key does not match.
Source code in ftmq/query/leaves.py
DatasetLeaf
EntityIdLeaf
GroupLeaf
Bases: RefLeaf
A property-type group (the prop_type column); entities is the reverse
lookup.
Source code in ftmq/query/leaves.py
IdLeaf
Leaf
A single condition: a comparator plus a cast value.
Subclasses set family / key and implement values() or override apply().
The comparator is not validated here but by
parse_lookup.
Source code in ftmq/query/leaves.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | |
wire
property
The field's spelling on a string surface, shared with aggregations.
apply(entity)
Test whether the entity matches this condition.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity
|
EntityProxy
|
The entity to test. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
Whether any entity value satisfies the comparator (for |
Source code in ftmq/query/leaves.py
field_dict()
Serialize this leaf to a family-tagged mapping.
Returns:
| Type | Description |
|---|---|
LeafDict
|
The |
Source code in ftmq/query/leaves.py
match(value)
Apply the comparator to one entity value (the in-memory match).
Source code in ftmq/query/leaves.py
match_row(statement)
values(entity)
Yield the entity values this leaf tests.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entity
|
EntityProxy
|
The entity to read values from. |
required |
Yields:
| Type | Description |
|---|---|
str
|
The string values (property values, schema name, ...). |
Source code in ftmq/query/leaves.py
LeafDict
Bases: TypedDict
Serialized form of a single Leaf condition.
Source code in ftmq/query/leaves.py
PropertyLeaf
Bases: RefLeaf
Matches a specific FtM property value (the prop column).
Source code in ftmq/query/leaves.py
RefLeaf
Bases: Leaf
A leaf reading its field through a Ref.
The ref validates the field name and reads the values; the leaf adds the comparator.
Source code in ftmq/query/leaves.py
SchemaLeaf
Bases: RefLeaf
Exact schema match.
Source code in ftmq/query/leaves.py
SchemataLeaf
Bases: Leaf
Is-a match: model[X] in entity.schema.schemata.
Source code in ftmq/query/leaves.py
names
property
The concrete schemata matched, including non-abstract descendants.
group_conjunction(leaves)
Group the leaves of one AND node into the sets that co-refer.
Conditions that could hold of one statement row must hold of the same row. A
field's leaves co-refer when they are all bounds (gt / gte / lt / lte),
so P(date__gte=a) & P(date__lt=b) is one date inside the window. Any other
repeated field keeps a per-leaf reading: M(dataset="d1") & M(dataset="d2")
is "in both datasets". Used by both the SQL and the in-memory evaluator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
leaves
|
'Iterable[Leaf]'
|
The leaf children of one AND node. |
required |
Returns:
| Type | Description |
|---|---|
'list[list[Leaf]]'
|
One group per co-referring set, in input order: a multi-leaf group holds bounds on one field, every other leaf is its own group. |
Source code in ftmq/query/leaves.py
is_row_scoped(leaf)
Whether a leaf tests a column describing one statement row.
True for the C columns and dataset, so AND-ed conditions on distinct ones
co-refer. Entity-wide fields (schema, schemata, the ids) and absence tests
(__null=True) are not row-scoped.
Source code in ftmq/query/leaves.py
leaf_from_dict(data)
Rebuild a leaf from its LeafDict.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
LeafDict
|
The |
required |
Returns:
| Type | Description |
|---|---|
Leaf
|
The reconstructed leaf. |
Source code in ftmq/query/leaves.py
make_leaf(family, key, value)
Build a leaf of a field family from a field__comparator lookup.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
family
|
str
|
|
required |
key
|
str
|
A lookup key, e.g. |
required |
value
|
Any
|
The lookup value. |
required |
Returns:
| Type | Description |
|---|---|
Leaf
|
The leaf. |
Raises:
| Type | Description |
|---|---|
QueryError
|
For an unknown family, meta field, property or group. |
Source code in ftmq/query/leaves.py
parse_lookup(key)
Split a field__comparator lookup key into its parts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
A lookup key such as |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, str]
|
A |
Raises:
| Type | Description |
|---|---|
QueryError
|
If the comparator suffix is not a valid comparator. |
Source code in ftmq/query/leaves.py
row_scoped_groups(groups)
Select the groups that co-refer across fields (columns of one statement row).
A field group_conjunction split
(repeated equality) is excluded, so M(dataset="d1") & M(dataset="d2") stays
two conditions next to a C(origin=...).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
groups
|
'list[list[Leaf]]'
|
The output of |
required |
Returns:
| Type | Description |
|---|---|
'list[list[Leaf]]'
|
The subset of those groups, as the same list objects. |
Source code in ftmq/query/leaves.py
Aleph bridge
The filter half of the Aleph URL-param grammar, wrapped by Query.to_params / from_params and to_string / from_string.
The Aleph / OpenAleph URL-param grammar: a bidirectional bridge between a
Query filter tree plus its aggregations and the filter: / exclude: /
empty: / metric: / facet params of openaleph_search.SearchQueryParser.
The param model is flat (AND across keys, OR within a key), so params_to_expr
always yields a flat AND of leaves and expr_to_params raises QueryError for a
cross-field OR or a negated group. exclude: is the negated match (~); not /
not_in have no param spelling. sort / limit / offset are handled by
Query.to_params / Query.from_params.
aggregations_to_params(aggs)
Project aggregation specs to openaleph metric: / facet params.
Each spec becomes metric:<func>=<field>, its groups facet=<field> (fields
spelled as the filter keys are). Facets apply across all metrics, so
differing per-metric groupings collapse to their union.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aggs
|
set[Agg]
|
The query's aggregation specs. |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
The |
Source code in ftmq/query/aleph.py
expr_to_params(expr)
Project a filter tree to Aleph filter: / exclude: / empty: params.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expr
|
Expr | None
|
The filter tree (or |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
The Aleph param mapping. |
Raises:
| Type | Description |
|---|---|
QueryError
|
If the tree is not Aleph-expressible (a cross-field |
Source code in ftmq/query/aleph.py
normalize_multidict(args)
Coerce params into a plain dict[str, list[str]].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
args
|
Any
|
A werkzeug |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
A mapping of each key to its list of string values. |
Source code in ftmq/query/aleph.py
params_to_aggregations(items)
Rebuild aggregation specs from openaleph metric: / facet params.
Inverse of
aggregations_to_params: every
facet groups every metric, and a facet without a metric: groups an
entity count.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
items
|
dict[str, list[str]]
|
A normalized param mapping. |
required |
Returns:
| Type | Description |
|---|---|
set[Agg]
|
The reconstructed aggregation specs (empty if there is neither a |
set[Agg]
|
|
Source code in ftmq/query/aleph.py
params_to_expr(items)
Build a filter tree from Aleph params (non-filter keys are ignored).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
items
|
dict[str, list[str]]
|
A normalized param mapping (see
|
required |
Returns:
| Type | Description |
|---|---|
Expr | None
|
The flat AND-of-leaves filter tree, or |
Source code in ftmq/query/aleph.py
params_to_string(params)
Render an Aleph param mapping as a URL query string.
Keys are sorted; value order within a key is kept (sort priority).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
params
|
dict[str, list[str]]
|
The param mapping. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A |
Source code in ftmq/query/aleph.py
string_to_params(value)
Parse an Aleph URL query string into a param mapping.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
str
|
A |
required |
Returns:
| Type | Description |
|---|---|
dict[str, list[str]]
|
A mapping of each key to its list of url-decoded values. |
Source code in ftmq/query/aleph.py
RQL bridge
RQL support for nested filter trees, used by Query.from_rql.
RQL (Resource Query Language) bridge.
RQL nests named operators, e.g.
and(eq(schema,Person),or(eq(properties.name,jane),eq(group.countries,de))), so
unlike the flat Aleph params it carries any & | ~ tree. Aggregations map to
RQL's sum / min / max / mean / count / aggregate(...) and the
projection to select(...), side by side with the filter under a top-level
and.
Fields use the shared wire spelling (properties.<name>, group.<name>,
context.<name>, bare meta fields and year); any other bare name is read as a
property.
expr_to_rql(expr)
Convert an Expr tree to an RQL AST ({"name": ..., "args": [...]}).
Source code in ftmq/query/rql.py
parse_rql(value)
Parse an RQL string into a filter tree, aggregation specs and a projection.
Raises:
| Type | Description |
|---|---|
QueryError
|
If the RQL uses an unsupported operator or field. |
Source code in ftmq/query/rql.py
rql_to_expr(data)
Convert a parsed RQL AST ({"name": ..., "args": [...]}) to an Expr.
Source code in ftmq/query/rql.py
to_rql(expr, aggs=(), selection=())
Serialize a filter tree, aggregation specs and a projection to an RQL string.
Raises:
| Type | Description |
|---|---|
QueryError
|
If a filter leaf uses a comparator with no RQL equivalent
( |
Source code in ftmq/query/rql.py
Aggregations
The A node, the Agg spec and the in-memory Aggregator. See the aggregation guide.
Aggregations: a projection over the matched entities, not a filter.
A builds one immutable
Agg spec per func=<ref> pair and is passed to
Query.aggregate.
Aggregator runs the specs in memory; the
SQL backend compiles the same specs.
A
An aggregation projection node: A(sum=P("amountEur"), by=P("beneficiary")).
Each keyword is a function (min, max, sum, avg, count) over one or
more refs; by= groups by one or more refs. It does not compose with
& | ~; pass it to Query.aggregate.
Examples:
A(sum=P("amountEur"), by=P("beneficiary"))
A(count=M("id"), by=[G("countries"), Year()])
A(sum=[P("amountEur"), P("amount")])
Source code in ftmq/query/aggregations.py
Agg
dataclass
An immutable aggregation spec: a function over a ref, optionally grouped.
Built via A.
Source code in ftmq/query/aggregations.py
key
property
The wire spelling of the aggregated field.
Aggregator
In-memory accumulator running Agg specs.
Holds all mutable state, so use a fresh instance per run.
Source code in ftmq/query/aggregations.py
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | |
result
property
The reduced result, keyed by the wire spelling of each field.
{func: {field: value}, "groups": {group: {func: {field: {bucket: value}}}}},
empties removed, each group capped to its top buckets.
apply(proxies)
Collect every entity while passing the stream through unchanged.
collect(proxy)
Accumulate one entity's values into every spec.
Source code in ftmq/query/aggregations.py
FacetOrder
dataclass
Ranks facet buckets by a grouped metric instead of by entity count.
Wire spelling: <func>:<field>[:asc].
Source code in ftmq/query/aggregations.py
wire
property
E.g. sum:properties.amountEur or count:id:asc.
from_wire(value)
classmethod
Parse the wire spelling (:desc is accepted too).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
str
|
E.g. |
required |
Returns:
| Type | Description |
|---|---|
FacetOrder
|
The facet order. |
Source code in ftmq/query/aggregations.py
orders(agg)
Whether this ranks by agg (ignoring its grouping).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agg
|
Agg
|
An aggregation spec. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in ftmq/query/aggregations.py
aggregations_from_dict(data)
Rebuild specs from the output of aggregations_to_dict.
Source code in ftmq/query/aggregations.py
aggregations_to_dict(aggs)
Serialize specs to sorted {"func", "field", "by"?} dicts (wire spellings).
Source code in ftmq/query/aggregations.py
groupers(aggs)
make_agg(func, ref, groups=())
Validate and build an Agg spec; groups are sorted, so their order is moot.
Source code in ftmq/query/aggregations.py
make_facet_order(func, ref, ascending=False)
Validate and build a FacetOrder.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
str
|
The aggregation function. |
required |
ref
|
Ref
|
The aggregated field. |
required |
ascending
|
bool
|
Rank the smallest values first. |
False
|
Returns:
| Type | Description |
|---|---|
FacetOrder
|
The facet order. |
Source code in ftmq/query/aggregations.py
reduce_values(func, values)
Reduce collected values with an aggregation function (None if empty).
Source code in ftmq/query/aggregations.py
SQL
A store passes its SqlSource to Query.compile (or builds Sql(query, source) directly). Partition pruning is prune={column: function}, one rule per partition column.
The statement source a Query compiles against.
Stores own one and pass it to Sql /
Query.compile; a store with extra columns (a lake /
sharded table) supplies its own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
Any
|
The SQLAlchemy |
required |
id_column
|
str
|
The entity-identity column name (default |
'canonical_id'
|
prune
|
dict[str, PruneFn] | None
|
Partition-pruning rules as |
None
|
base_filter
|
Any | None
|
A predicate folded into every compiled select and sub-select (e.g. a lake store's view filter). |
None
|
Source code in ftmq/query/sql.py
Build a prune rule for a partition column derived from the schema.
Used as a SqlSource prune rule (the lake
store's bucket): maps the query's schema / schemata filters to the
partitions of their schemata. Without a schema filter, or with a not /
not_in schema comparator, nothing is pruned.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
get_partition
|
Callable[[str], str]
|
Maps a schema name to its partition value. |
required |
Returns:
| Type | Description |
|---|---|
PruneFn
|
The prune rule. |
Source code in ftmq/query/sql.py
Compile a Query to SQLAlchemy selects over a statement table.
Every leaf lifts to an entity-level canonical_id IN (...) membership, so a
filter selects whole entities, assembled from all of their statements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
q
|
Query
|
The query. |
required |
source
|
SqlSource | None
|
The statement source (default: the nomenklatura statement table). |
None
|
scope
|
Iterable[str] | None
|
Restrict to entities with a statement in one of these datasets. |
None
|
Source code in ftmq/query/sql.py
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 | |
grouped_aggregations(grouper, limit=None)
Every aggregation spec grouped by grouper, as one unioned select.
Rows are (field, func, group_value, value). Specs aggregate over the
distinct (entity, group value) pairs of the matching entities, so a
multi-valued group property does not multiply rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
grouper
|
Ref
|
The field reference to group by. |
required |
limit
|
int | None
|
Keep the top |
None
|
Returns:
| Type | Description |
|---|---|
Select
|
The unioned select. |
Source code in ftmq/query/sql.py
lookup(ref)
Where a field reference reads from in this source.
A meta / context ref reads its own column (no row predicate); a property
or group ref reads value, selecting its rows by prop / prop_type.