Skip to content

tdfs4ds.feature_values

tdfs4ds.feature_values

Entity values and feature extremes, computed in the database.

Two questions a business user asks before any chart, answered without pulling a table out of Teradata (every number below is an aggregate or a TOP n read):

  • :func:entity_sample - which values does an entity take? A sample of the stored keys and how many there are ("give me 5 TICKER values").
  • :func:feature_extremes - who sits at the ends of a feature's distribution? Its statistics, the entities with the n highest and n lowest values, and the outliers by Tukey's rule (below Q1 - 1.5 IQR or above Q3 + 1.5 IQR).

Both read the feature store's own storage tables (FS_T_*) at the current valid time, or at as_of. Layers as elsewhere: *_sql builders are pure, the two public functions do the reads, and nothing is cached.

TUKEY_K module-attribute

TUKEY_K = 1.5

_NUMERIC_TYPES module-attribute

_NUMERIC_TYPES = {'I', 'I1', 'I2', 'I8', 'F', 'D', 'N'}

_TEXT_CODES module-attribute

_TEXT_CODES = {'CV', 'CF', 'CO'}

qualified

qualified(database, object_name, force=False)

Build db.obj with each part quoted only as needed.

qualified('TDB', 'FS_X') == 'TDB.FS_X' (unchanged for ordinary names); qualified('SVC@CORP', 'FS_X') == '"SVC@CORP".FS_X'. An empty/None database yields the bare object name, so unqualified callers keep working.

force=True quotes both parts unconditionally — only for the sites that have always emitted quotes and whose exact text is already persisted (dataset view DDL, returned volatile-table names).

quote_ident

quote_ident(name, force=False)

Return name as a Teradata identifier, quoting it only if required.

Idempotent: an already-quoted name is returned unchanged rather than being wrapped a second time. Embedded quotes are escaped as "".

Parameters

name : str The raw object/database name. force : bool, default False Quote even when the name does not need it. Use only at the few sites that have always emitted unconditional quotes and whose exact output is already baked into persisted DDL (see feature_store/feature_query_retrieval.py) — elsewhere forcing would change the SQL of existing stores for no reason.

sql_literal

sql_literal(value)

Escape value for use inside a single-quoted SQL string literal.

For the DBC probes and catalog predicates that compare a name as data (WHERE DatabaseName = '…'). The caller supplies the surrounding quotes.

_execute

_execute(sql)

_valid_at

_valid_at(at: Optional[str]) -> str

The rows valid at at (a normalised timestamp) or now, as a predicate usable inside a NONSEQUENCED read (a derived table refuses CURRENT VALIDTIME).

_qualifier

_qualifier(at: Optional[str]) -> str

entity_tables

entity_tables(entity: str, data_domain: Optional[str] = None) -> list

[{domain, database, table}]: the storage tables keyed by entity (its exact key column set), in one domain or all of them.

entity_values_sql

entity_values_sql(tables: list, columns: list, *, at: Optional[str] = None) -> str

The distinct key values stored in tables at at (or now): one derived table per storage table, unioned (a temporal qualifier cannot open a UNION branch, Error 9345, so each read sits in its own derived table).

entity_sample

entity_sample(entity: str, *, data_domain: Optional[str] = None, n: int = 5, as_of=None) -> dict

A sample of the values entity takes in the feature store, and their count.

Parameters:

Name Type Description Default
entity str

the entity name as registered (its key columns, e.g. 'TICKER' or 'Category,CustomerID').

required
data_domain Optional[str]

one domain; None reads every domain holding the entity.

None
n int

how many values to return (a random SAMPLE in the database).

5
as_of

a valid time (default: now).

None

Returns {entity, columns, total, values: [{col: value}], domains, tables, sql}; total is the number of distinct key values.

feature_stats_sql

feature_stats_sql(table: str, where: str, *, at: Optional[str] = None) -> str

One pass: count, nulls, min, quartiles, max, mean, standard deviation.

feature_ends_sql

feature_ends_sql(table: str, where: str, keys: list, *, n: int = 5, highest: bool = True, at: Optional[str] = None) -> str

The n entities with the highest (or lowest) value.

feature_outliers_sql

feature_outliers_sql(table: str, where: str, keys: list, low: float, high: float, centre: float, *, n: int = 5, at: Optional[str] = None) -> tuple

(count_sql, examples_sql): the values outside [low, high], the examples being the n farthest from centre (the median).

feature_extremes

feature_extremes(feature: str, *, entity=None, data_domain=None, n: int = 5, as_of=None, process_id: Optional[str] = None) -> dict

Statistics, the n highest and lowest entities, and the outliers of a feature.

Every number is computed in the database on the feature's storage table at the current valid time (or as_of): one aggregate pass for the statistics, then TOP n reads. Outliers follow Tukey's rule (outside [Q1 - 1.5 IQR, Q3 + 1.5 IQR]); when the IQR is 0 the rule cannot separate anything, so the values that differ from the median are given.

Returns {feature, entity, data_domain, table, keys, numeric, stats, top, bottom, outliers: {rule, low, high, count, examples}, notes}; each entry of top / bottom / examples is {"key": {col: value}, "value": v}. A non-numeric feature gets only stats (count, nulls) and a note.

typed_literal

typed_literal(value, type_code: str) -> Optional[str]

value as a SQL literal of the key column's type, or None when it cannot be one (a word for a numeric key). Equality with a typed literal on the bare column lets Teradata use the primary index; TRIM(col) would scan.

key_filter

key_filter(keys: list, types: dict, values) -> Optional[str]

(col IN (...)) OR ... over the key columns a value can belong to; None when no value fits any column. A dict value {col: v} gives one AND term.

find_entity_values

find_entity_values(entity: str, candidates, *, data_domain: Optional[str] = None, limit: int = 50) -> list

The candidates that are stored values of the entity, as key dicts (at most limit). One query per storage table, typed equality.

feature_values_for

feature_values_for(features, entity_values, *, entity=None, data_domain=None, as_of=None) -> dict

The values of features for the given entity values, at the valid time.

Parameters:

Name Type Description Default
features

a feature name or a list (same entity).

required
entity_values

values of the entity key ('NVDA', 33357), or dicts {column: value} for a composite key.

required
entity, data_domain

choose between same-named features.

required
as_of

a valid time (default: now).

None

One query per storage table (CURRENT VALIDTIME or AS OF), on each feature's most recently written process version, keyed by typed equality so the primary index is used. Returns {"keys", "rows": [{"key": {...}, "values": {feature: value}}], "features": [{"name", "entity", "data_domain", "process_id", "table"}], "as_of", "notes"}.

entity_profile

entity_profile(entity: str, entity_values, *, data_domain: Optional[str] = None, as_of=None, limit: Optional[int] = None) -> dict

Every feature of the entity for the given entity values, at the valid time.

One read per storage table of the entity (all its features at once, typed equality on the key), names from the feature catalog. A feature computed by several processes shows the most recently written one (as plots do), and is named in several_processes. Returns {"entity", "keys", "rows": [{"key", "values": {feature: value}}], "domains", "as_of", "truncated", "several_processes"}; at most limit features (tdfs4ds.AGENT_LIST_MAX_ITEMS by default) per entity value.

_plain

_plain(v)

A database value as a plain Python value (strings trimmed, Decimals as float).

_rows

_rows(cursor, keys: list) -> list