lumix.indexing.dimensions.LXIndexDimension¶
- class lumix.indexing.dimensions.LXIndexDimension(model_type, key_func, filter_func=None, label=None, _data=None, _session=None)[source]¶
Represents a single dimension in multi-dimensional model indexing.
An LXIndexDimension defines one dimension of a potentially multi-dimensional index space. It encapsulates the model type, indexing function, optional filters, and data source for that dimension. Dimensions can be combined via LXCartesianProduct to create multi-model indexed variables and constraints.
This class is central to LumiX’s data-driven modeling approach, enabling automatic expansion of variables and constraints across data instances with type safety and IDE support.
- Type Parameters:
TModel: The data model type for this dimension (e.g., Driver, Product, Date)
- Parameters:
- model_type¶
The Python class representing the data model for this dimension
- key_func¶
Function to extract the index key from a model instance
- filter_func¶
Optional predicate to filter which instances to include
- label¶
Optional human-readable label for this dimension
- _data¶
Direct data instances (mutually exclusive with _session)
- _session¶
ORM session for querying instances (mutually exclusive with _data)
Examples
Basic dimension with direct data:
driver_dim = ( LXIndexDimension(Driver, lambda d: d.id) .from_data(drivers) )
Dimension with filtering:
active_driver_dim = ( LXIndexDimension(Driver, lambda d: d.id) .from_data(drivers) .where(lambda d: d.is_active and d.years_experience >= 2) )
Dimension with ORM:
product_dim = ( LXIndexDimension(Product, lambda p: p.sku) .from_model(db_session) .where(lambda p: p.in_stock) )
Compound key extraction:
route_dim = ( LXIndexDimension(Route, lambda r: (r.origin, r.destination)) .from_data(routes) )
See also
LXCartesianProduct: Combines dimensionsindexed_by_product: Uses dimensionsDriver Scheduling Example (examples/02_driver_scheduling): Real-world usage
Note
Index dimensions follow the “late binding” pattern - data instances are not retrieved until the dimension is actually used during model solving. This allows dimensions to be defined before data is available and supports dynamic data sources.
- __init__(model_type, key_func, filter_func=None, label=None, _data=None, _session=None)¶
Methods
__init__(model_type, key_func[, ...])from_data(data)Provide data instances directly for this dimension.
from_model(session)Configure dimension to query data from an ORM session.
Retrieve and filter data instances for this dimension.
where(predicate)Apply a filter predicate to this dimension.
Attributes
- __deepcopy__(memo)[source]¶
Custom deepcopy that detaches ORM sessions and handles lambda closures.
This method enables what-if analysis on models using ORM data sources by: 1. Materializing lazy-loaded ORM data before copying 2. Detaching ORM objects from database sessions 3. Safely copying lambda functions that may capture ORM objects
- Parameters:
memo – Dictionary for tracking circular references during deepcopy
- Returns:
Deep copy of this dimension with all ORM dependencies resolved
Note
After copying, the new dimension will have _session=None and all data stored in _data as detached objects safe for pickling.
- __getstate__()[source]¶
Support for pickle protocol - detach ORM sessions before pickling.
- Returns:
Dictionary of instance state safe for pickling
- __setstate__(state)[source]¶
Support for pickle protocol - restore from pickled state.
- Parameters:
state – Dictionary of instance state from pickling
- from_data(data)[source]¶
Provide data instances directly for this dimension.
This method configures the dimension to use a pre-existing list of model instances. Use this when you have data already loaded in memory or when not using an ORM.
- Parameters:
data (
List[TypeVar(TModel)]) – List of model instances for this dimension- Return type:
LXIndexDimension[TypeVar(TModel)]- Returns:
Self for method chaining
Examples
Basic usage:
drivers = [Driver("D1", "Alice"), Driver("D2", "Bob")] dim = LXIndexDimension(Driver, lambda d: d.id).from_data(drivers)
With filtering:
dim = ( LXIndexDimension(Driver, lambda d: d.id) .from_data(drivers) .where(lambda d: d.is_active) )
Note
This method is mutually exclusive with from_model(). If both are called, the last call takes precedence.
- from_model(session)[source]¶
Configure dimension to query data from an ORM session.
This method configures the dimension to query instances from a database using an ORM session (e.g., SQLAlchemy, Django ORM). The actual query is executed lazily when get_instances() is called.
- Parameters:
session (
Any) – ORM session object (SQLAlchemy Session, Django ORM manager, etc.)- Return type:
LXIndexDimension[TypeVar(TModel)]- Returns:
Self for method chaining
Examples
SQLAlchemy session:
from sqlalchemy.orm import Session dim = ( LXIndexDimension(Driver, lambda d: d.id) .from_model(db_session) .where(lambda d: d.is_active) )
With additional filtering:
dim = ( LXIndexDimension(Product, lambda p: p.sku) .from_model(session) .where(lambda p: p.stock_quantity > 0) )
Note
This method is mutually exclusive with from_data()
The actual database query happens during model solving, not at definition time
Filters applied via where() are evaluated in Python after the query
See also
lumix.utils.orm: ORM integration utilities
- get_instances()[source]¶
Retrieve and filter data instances for this dimension.
This method retrieves instances from the configured data source (either direct data or ORM query) and applies any filters specified via where(). This is typically called internally during model solving, not by user code.
- Return type:
- Returns:
List of model instances after filtering
- Raises:
ValueError – If no data source is configured (neither from_data() nor from_model() has been called)
Examples
The method is typically called internally, but can be used for inspection:
dim = ( LXIndexDimension(Driver, lambda d: d.id) .from_data(all_drivers) .where(lambda d: d.is_active) ) # Get filtered instances active_drivers = dim.get_instances() print(f"Found {len(active_drivers)} active drivers")
Note
For ORM-based dimensions, this triggers the database query
Filters are applied in Python after data retrieval
Results are not cached; each call may return different results if data changes
- Implementation Details:
The method follows this logic: 1. If _data is set, use it as the data source 2. Otherwise, if _session is set, query via ORM using LXTypedQuery 3. Otherwise, raise ValueError 4. Apply filter_func if present
- where(predicate)[source]¶
Apply a filter predicate to this dimension.
This method adds a filter that determines which model instances from this dimension should be included. Only instances where the predicate returns True will be included in the dimension’s expansion.
The filter is applied within the dimension itself, before any cross-dimension filters (where_multi) are applied when using cartesian products.
- Parameters:
predicate (
Callable[[TypeVar(TModel)],bool]) – A function that takes a model instance and returns True if it should be included, False otherwise- Return type:
LXIndexDimension[TypeVar(TModel)]- Returns:
Self for method chaining
Examples
Simple filter:
dim = ( LXIndexDimension(Driver, lambda d: d.id) .from_data(drivers) .where(lambda d: d.is_active) )
Complex filter with multiple conditions:
dim = ( LXIndexDimension(Product, lambda p: p.sku) .from_data(products) .where(lambda p: p.in_stock and p.price > 0 and not p.discontinued) )
Filter with attribute check:
dim = ( LXIndexDimension(Route, lambda r: (r.origin, r.dest)) .from_data(routes) .where(lambda r: r.distance < 1000 and r.is_operational) )
Note
Filters are evaluated in Python after data retrieval
Multiple where() calls will override previous filters (not combine them)
For multi-dimensional filtering across dimensions, use where_multi() on the variable
See also
lumix.core.variables.LXVariable.where_multi(): Cross-dimension filteringget_instances(): Where filtering is applied