What a sync run cannot do: write an element no sync block owns.
A sync run replaces what owner records wrote, so everything it writes must be
replaceable: every edge is owned by a resource in the run, and every owned
type carries a hash field (the sync aspect). Checked before anything is
staged. A vertex type the run does not own must be written key-only; that is
checked on the folded rows (:func:graflo.hq.sync.run.check_key_only).
Classes
Functions:
hash_fields(schema, owned)
Each type of owned that has one, mapped to its set_by: sync field.
Source code in graflo/hq/sync/refusals.py
| def hash_fields(schema: Schema, owned: set[str]) -> dict[str, str]:
"""Each type of *owned* that has one, mapped to its ``set_by: sync`` field."""
vc = schema.core_schema.vertex_config
out: dict[str, str] = {}
for vertex in sorted(owned):
fields = [f.name for f in vc.properties(vertex) if f.set_by == "sync"]
if len(fields) > 1:
raise ValueError(
f"vertex {vertex!r} has several fields set by sync: {fields}"
)
if fields:
out[vertex] = fields[0]
return out
|
sync_refusals(schema, ingestion_model, resources=None)
Why a sync run of resources (all when None) cannot start; empty when it can.
Source code in graflo/hq/sync/refusals.py
| def sync_refusals(
schema: Schema, ingestion_model: IngestionModel, resources: list[str] | None = None
) -> list[str]:
"""Why a sync run of *resources* (all when ``None``) cannot start; empty when it can."""
in_scope = [
r for r in ingestion_model.resources if resources is None or r.name in resources
]
owners = [r for r in in_scope if r.sync is not None]
if not owners:
return ["no resource in the run declares a sync block"]
reasons: list[str] = []
owned = owned_edges(in_scope)
core = schema.core_schema
vc = core.vertex_config
for resource in in_scope:
produced = ingestion_model.fetch_resource(resource.name).collect_vertex_names()
for edge_id in dict(core.edge_config.items()):
if edge_id not in owned and may_emit(resource, edge_id, produced):
reasons.append(
f"{resource.name}: writes edge {edge_id}, which no sync block owns"
)
for resource in owners:
assert resource.sync is not None
owns = resource.sync.owns
if not [f for f in vc.properties(owns) if f.set_by == "sync"]:
reasons.append(
f"{resource.name}: {owns!r} has no field set by sync; lift the "
"sync aspect (graflo lift --aspect sync)"
)
return reasons
|