Filters

Note

There is no need to apply filters manually if you are executing scripts as Spine Toolbox Tools.

The spinedb_api.filters module provides filters that alter the queries of spinedb_api.DatabaseMapping such that the queries return filtered or transformed data. The filters are transparent to use: once applied, the database mapping can be read exactly the same way as without filters.

Note

A database mapping that has filters applied should be considered read-only as any data modifying functionality is oblivious of filters.

Filters are generated by the *_config() functions in the filter-specific submodules of spinedb_api.filters. The functions return config dicts, dictionaries that should be treated as opaque objects and not to be messed with directly.

The usual way to apply a filter is to create a config dict, then add it to the database URL with spinedb_api.filters.tools.append_filter_config() before passing the URL to the spinedb_api.DatabaseMapping constructor. The snipped below demonstrates the application of a scenario filter this way:

from spinedb_api import DatabaseMapping
from spinedb_api.filters.scenario_filter import scenario_filter_config
from spinedb_api.filters.tools import append_filter_config

url = ...
scenario_filter = scenario_filter_config("coal_chp")
url = append_filter_config(url, scenario_filter)
with DatabaseMapping(url) as db_map:
   ...

If you already have a spinedb_api.DatabaseMapping instance, spinedb_api.filters.tools.apply_filter_stack() lets you apply all your filters to the database mapping.

Note

Filters applied by spinedb_api.filters.tools.apply_filter_stack() cannot affect data that has been fetched from the database before the application.

spinedb_api.DatabaseMapping.get_filter_configs() returns the current config dicts that have been applied to the database mapping. These can be inspected with the functions found in spinedb_api.filters. As an example, the code below checks if database mapping has a scenario filter:

import sys
from spinedb_api import DatabaseMapping
from spinedb_api.filters.scenario_filter import scenario_name_from_dict

url = sys.argv[1]
with DatabaseMapping(url) as db_map:
    filters = db_map.get_filter_configs()
    if filters:
        scenario_names = (scenario_name_from_dict(config_dict) for config_dict in filters)
        scenario_name = next(iter(name for name in scenario_names if name is not None), None)
        if scenario_name:
            print(f"Scenario filter detected: {scenario_name}")