Sollen Dokumente von einem enaio zum anderen (oder von einem Schrank in einen neuen migriert werden) stellen sich viele Fragen. Wie umgehen mit Notizen, Notizverweisen, „grünen Pfeilen“ etc. Auch variantierte Dokumente sind ein grosses Thema. Variantenbäume können komplex sein, nicht immer ist das Ursprungselement einer Variante auch dessen Vaterelement. Die letzte Variante muss nicht die aktive Variante sein.
Die Methode zum Variantenimport via dms.XmlInserts
bzw. Variantenimport via xml_import() unterstützt leider das Setzen des korrekten „…AUS“-Werts nicht. Dies ist möglich mit std.GetDocVariant
, allerdings scheint dies nicht die gleichzeitige Übergabe neuer Metadaten zu erlauben.
Da sich bei Varianten aber Dokumentinhalte und Metadaten unterscheiden können, ist eine nachträgliche Bearbeitung, z. B. mit dms.SetActiveVariant
gefolgt von einem dms.XmlUpdate
oder ähnlichem nötig. Bei Migrationsszenarien sollen aber nur die nötigen Aktionen ausgeführt werden, um Zeit zu sparen und die Dokumenthistorien schlank zu halten.
Variantenbaum auslesen
Der Variantenbaum lässt sich noch relativ einfach auslesen, hier ein kurzes Beispiel zum oben gezeigten Baum:
from ecmind_blue_client.query_condition_field import QueryConditionField as Field
from ecmind_blue_client.query_condition_group import QueryConditionGroup as Group
from ecmind_blue_client.const import QueryOperators
from ecmind_blue_client import Job
from ecmind_blue_client.tcp_client import TcpClient as Client
from XmlElement import XmlElement as X
client = Client('localhost', 4000, 'TestClient', 'root', 'optimal', False)
xml = X('DMSQuery',
a={'requesttype': 'HOL'},
s=[X('Archive',
s=[X('ObjectType',
a={'internal_name': 'UnittestDoc'},
s=[X('Conditions',
s=[X('ConditionObject',
a={'internal_name': 'UnittestDoc'},
s=[X('FieldCondition',
a={'internal_name': 'OSID', 'operator': QueryOperators.EQUAL.value},
s=[X('Value', t='167944')]
)]
)]
)]
)]
)]
)
job = Job(
jobname='dms.GetResultList',
Flags=0,
XML=xml,
RequestType='HOL',
Variants=1
)
result = client.execute(job)
result_xml = X.from_string(result.values['XML'])
print(result_xml)
Dies ergibt:
<DMSContent format="HOL" output_language="0" version="9.0.780.18346" timestamp="2021-03-19T17:32:00" user="ROOT" station="ecm2" instance="TestClient">
<Archive name="Unittest" id="7" osguid="9D4271A85AF74976B31BDE76327B3A6D">
<ObjectType name="Unittest Doc" id="262151" maintype="4" cotype="7" osguid="42C0631FCA5F440886FA800B7DB82072" internal_name="UnittestDoc" type="DOCUMENT" modul="MULTIDOC" table="object10">
<ObjectList>
<Object id="167948">
<Fields />
<DocumentVariants>
<DocumentVariant is_active="0" doc_id="167944" doc_ver="Original" doc_parent="0">
<DocumentVariant is_active="0" doc_id="167946" doc_ver="1.0.0" doc_parent="167944" />
<DocumentVariant is_active="0" doc_id="167947" doc_ver="2.0.0" doc_parent="167946">
<DocumentVariant is_active="1" doc_id="167948" doc_ver="2.1.0" doc_parent="167947">
<DocumentVariant is_active="0" doc_id="167952" doc_ver="2.1.1" doc_parent="167948" />
<DocumentVariant is_active="0" doc_id="167954" doc_ver="2.1.2" doc_parent="167948" />
</DocumentVariant>
</DocumentVariant>
<DocumentVariant is_active="0" doc_id="167949" doc_ver="3.0.0" doc_parent="167948" />
<DocumentVariant is_active="0" doc_id="167956" doc_ver="4.0.0" doc_parent="167944" />
</DocumentVariant>
</DocumentVariants>
</Object>
</ObjectList>
<Statistics startpos="0" pagesize="-1" total_hits="1" />
</ObjectType>
</Archive>
<Messages />
</DMSContent>
Universalfunktion?
Nun wäre eine Helper-Funktion denkbar, welche einen vollen Variantenbaum mit minimalen API-Schritten erzeugt.
Dies lässt aber folgende Fragen zum Design offen:
- Für jede Quellvariante muss noch ein separates
dms.GetObjectDetails
ausgelöst werden, dadms.GetResultList
die Metadaten von Varianten nicht auslesen kann. -
dms.GetObjectDetails
liefert aber nicht alle Metadaten aus dem Bereich der Basisparameter, welche ggf. auf technischen/historischen Felder mit migriert werden sollen. - Wird
dms.SetActiveVariant
anstelle vondms.XmlInserts
mit dem Attributeparentvariant_id
genutzt, müsste zum Sparen von API-Aufrufen geprüft werde, ob Metadaten zum Elternelement überhaupt abweichen und nur in diesem Fall eindms.XmlUpdate
ausgelöst werden. - Die Importreihenfolge muss korrekt sein, jeder
Parent
muss vor seinenChild
-Dokumenten angelegt werden. - Für jede Quelldatei muss ein
std.StoreInCacheById
ausgelöst werden und diese Dateien für die Migration vorgehalten werden. - Wie ist überhaupt umzugehen mit Teilmigrationen? Ist es möglich, eine Migration vorzubereiten oder müssten dann bei veränderten, variantierten Quelldokumenten die vorab erzeugte Dokumenthierarchie nochmals gelöscht werden, um zuverlässige Ergebnisse zu erhalten?
- Was ist, wenn der Migrationsprozess an einer beliebigen Stelle abbricht?
- Was ist, wenn sich nicht aktive Varianten verändern beziehungsweise die Dokumente einer Variante inhaltlich verändern? Checksummenvergleich aller Variantendokumente in Quelle und Ziel? („Cache invalidation is hard.“)