export()
Exportiert Organisationsdaten, Workflowprojekte und Workflowmodelle über wfm.Export.
Der Server antwortet mit einer einzelnen .exp-Datei: UTF-16-kodiertes XML mit dem
Wurzelelement <WorkflowImport>, also genau das, was wfm.Import wieder entgegennimmt.
Die ganze Organisation passt in einen Aufruf: das Wurzelprojekt mit complete=True
auswählen. Der Server dokumentiert das als „all projects or workflows hanging under the
project", der Baum muss also nicht ausgeschrieben werden.
1. Signatur
-
Sync
-
Async
ecm.workflow.export(
organisation: str | ECMOrganisation | None = None,
*,
projects: Iterable[ECMWorkflowProjectSelection] | None = None,
include_organisation: bool = True,
include_report_configs: bool = False,
report_config_ids: Iterable[str] = (),
include_routing_list_templates: bool = False,
routing_list_template_ids: Iterable[str] = (),
) -> list[JobResponseFile]
await ecm.workflow.export(
organisation: str | ECMOrganisation | None = None,
*,
projects: Iterable[ECMWorkflowProjectSelection] | None = None,
include_organisation: bool = True,
include_report_configs: bool = False,
report_config_ids: Iterable[str] = (),
include_routing_list_templates: bool = False,
routing_list_template_ids: Iterable[str] = (),
) -> list[JobResponseFile]
2. Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
|
|
Die Organisation als GUID oder als |
|
|
Die zu exportierenden Projekte und Workflowmodelle. |
|
|
Organisationsstruktur mit exportieren (Serverparameter |
|
|
Report-Konfigurationen der Organisation mit exportieren. |
|
|
Die zu exportierenden Report-Konfigurationen. Leer zusammen mit
|
|
|
Adhoc-Verteilerlisten-Vorlagen der Organisation mit exportieren. |
|
|
Die zu exportierenden Vorlagen. Leer zusammen mit
|
3. Rückgabewert
Die Exportdateien, so wie der Server sie liefert. Gegen enaio 12.0 gemessen ist es in jedem
Fall genau eine .exp-Datei. Mit file.store(pfad) wird sie auf die Platte geschrieben.
4. ECMWorkflowProjectSelection
Ein Knoten des WFProjectTree-Parameters.
| Feld | Typ | Beschreibung |
|---|---|---|
|
|
Das zu exportierende Projekt als GUID oder als |
|
|
Alles unterhalb des Projekts exportieren. |
|
|
Verschachtelte Projektauswahl, um einzelne Zweige zu adressieren. |
|
|
GUIDs einzelner Workflowmodelle unterhalb dieses Projekts. |
5. Beispiele
5.1. Ganze Organisation exportieren
-
Sync
-
Async
from ecmind_blue_client.ecm import ECMWorkflowProjectSelection, ECMWorkflowProjectType
root = next(p for p in ecm.workflow.projects() if p.type is ECMWorkflowProjectType.ROOT)
files = ecm.workflow.export(projects=[ECMWorkflowProjectSelection(root, complete=True)])
files[0].store(f"{root.name}.exp")
from ecmind_blue_client.ecm import ECMWorkflowProjectSelection, ECMWorkflowProjectType
projects = await ecm.workflow.projects()
root = next(p for p in projects if p.type is ECMWorkflowProjectType.ROOT)
files = await ecm.workflow.export(projects=[ECMWorkflowProjectSelection(root, complete=True)])
files[0].store(f"{root.name}.exp")
6. Exportdatei lesen
import xml.etree.ElementTree as ET
document = ET.fromstring(files[0].bytes().decode("utf-16"))
print(document.tag) # WorkflowImport
6.1. Aufbau
<WorkflowImport EngineVersion ExportSubVersion ExportEncoding>
<Organisation Id Name>
<OrgStructure/> <!-- Klassen, Attribute, Objekte -->
<Eventtypes/>
<WorkflowProject Id Name Type Description CreatorId CreationTime
Priority ProcCount VersionCount> <!-- rekursiv verschachtelt -->
<Workflow Id Name Description State Version PackageId IconId
CreatorId CreationTime/> <!-- nur unter Type=3 -->
</WorkflowProject>
</Organisation>
<ClientTypes/>
<ResourceLanguages/>
</WorkflowImport>
<WorkflowProject> ist beliebig tief verschachtelt und bildet damit die Projekt-Hierarchie
ab, die projects() nicht liefert. Priority, ProcCount
und VersionCount stehen nur hier.
6.2. Ordnerstruktur je Workflowmodell
from pathlib import Path
import xml.etree.ElementTree as ET
document = ET.fromstring(files[0].bytes().decode("utf-16"))
def walk(node, path):
for project in node.findall("WorkflowProject"):
here = path + [project.get("Name", "")]
for model in project.findall("Workflow"):
yield Path(*here) / f"{model.get('Name')}.xml"
yield from walk(project, here)
for target in walk(document.find("Organisation"), []):
print(target) # Workflowprojekte/test1/Test/WF.xml
Projektnamen sind nicht eindeutig — Kollisionen sind selbst zu behandeln, siehe Projekt-Hierarchie nachbilden.
6.3. Organisation und Workflows getrennt exportieren
Die grosse Datei nachträglich zu zerlegen ist heikel: ein Teilstück ist nur dann wieder
importierbar, wenn es die organisationsweiten Abschnitte mitträgt — <ClientTypes> und
<ResourceLanguages> auf WorkflowImport-Ebene, <Eventtypes> auf Organisation-Ebene,
dazu die Kette der <WorkflowProject>-Vorfahren. Hinzu kommt, dass Events auf
Client-Type-IDs verweisen, darunter die Sentinel-ID FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, die
in <ClientTypes> gar nicht definiert ist.
Einfacher und ohne dieses Risiko: den Server die Teile selbst erzeugen lassen. Die
Organisationsstruktur einmal ohne Projekte, dann je Workflowfamilie einen Aufruf mit
include_organisation=False — sonst steckt <OrgStructure> in jeder einzelnen Datei.
from pathlib import Path
import xml.etree.ElementTree as ET
document = ET.fromstring(files[0].bytes().decode("utf-16"))
# Organisationsstruktur einmal, ohne Projekte
ecm.workflow.export()[0].store("organisation.xml")
def familien(node, ordner, kette):
"""Ordner nur für Projekte, Dateien je Familie; die Kette führt zur Familie."""
for project in node.findall("WorkflowProject"):
name, project_id, typ = project.get("Name", ""), project.get("Id"), project.get("Type")
if typ == "1": # Wurzelprojekt
yield from familien(project, ordner / name, kette)
elif typ == "2": # Workflowprojekt
yield from familien(project, ordner / name, kette + [project_id])
else: # Workflowfamilie
yield ordner, name, kette, project_id
for ordner, name, kette, family_id in familien(document.find("Organisation"), Path("."), []):
auswahl = ECMWorkflowProjectSelection(family_id, complete=True)
for vorfahre in reversed(kette):
auswahl = ECMWorkflowProjectSelection(vorfahre, children=[auswahl])
teil = ecm.workflow.export(projects=[auswahl], include_organisation=False)[0]
ordner.mkdir(parents=True, exist_ok=True)
teil.store(ordner / f"{name}.xml")
Ergebnis:
organisation.xml 63 940 B Workflowprojekte/test1/Adhoc.xml 1154 822 B Workflowprojekte/test1/Taskflow.xml 726 460 B Workflowprojekte/test1/Test.xml 87 824 B (enthält die Modelle Test und WF) Workflowprojekte/test2/Test2.xml 26 758 B
Zwei Feinheiten:
-
Die Vorfahrenkette darf beim Wurzelprojekt beginnen, muss aber nicht — oben ist es weggelassen, der Server löst über die IDs auf.
-
Eine Familie kann mehrere Modelle enthalten, die dann in derselben Datei landen. Wer je Modell eine Datei will, wählt das Blatt statt mit
complete=Truemitworkflows=[model_id]und nimmt die Modell-IDs aus den<Workflow>-Elementen.
|
|
|
|
7. Siehe auch
-
projects()— Projektliste und Wurzelprojekt -
organisations()— Organisationen auflisten