Source code for randonneur.generic_transformation
from functools import partial
from typing import Callable, Dict, List, Optional
from loguru import logger
from tqdm import tqdm
from randonneur.config import MigrationConfig
from randonneur.utils import FlexibleLookupDict, apply_mapping
[docs]
def generic_transformation(
graph: List[dict],
migrations: dict,
verb_dispatch: Dict[str, Callable],
is_edges: bool = True,
config: Optional[MigrationConfig] = None,
) -> List[dict]:
config = config or MigrationConfig()
label = "edges" if is_edges else "nodes"
progressbar = (
partial(tqdm, desc=f"Transforming graph {label}") if config.verbose else lambda x: iter(x)
)
if config.mapping:
migrations = apply_mapping(
migrations=migrations, mapping=config.mapping, verbs=config.verbs
)
verbs = list(filter(lambda x: x in verb_dispatch and x in migrations, config.verbs))
logger.info("Can apply the following transformation verbs: {v}", v=verbs)
flds = {
verb: FlexibleLookupDict(
input_data=migrations[verb],
fields_filter=config.fields,
case_sensitive=config.case_sensitive,
)
for verb in verbs
if verb != "create"
}
if is_edges and "create" in migrations and "create" in verbs and not config.node_filter:
logger.warning(
"""
`migrations` has `create` section.
No `node_filter` is configured, meaning that these nodes will be added to all nodes.
This is almost never the desired behaviour, consider removing `create` from the `verb` input.
"""
)
if "create" in migrations and "create" in verbs:
flds["create"] = migrations["create"]
if is_edges:
for node in progressbar(graph):
if config.node_filter and not config.node_filter(node):
continue
for verb in verbs:
verb_dispatch[verb](
node=node,
migration_fld=flds[verb],
config=config,
)
else:
for verb in progressbar(verbs):
verb_dispatch[verb](
graph=graph,
migration_fld=flds[verb],
config=config,
)
return graph