update()
Aktualisiert ein bestehendes Objekt auf dem Server. Intern wird dms.XMLUpdate verwendet. Die übergebene Modell-Instanz wird nicht verändert.
ECM-Modell-Referenz — vollständige Beschreibung von system.is_modified, system.modified_fields, system.modified_table_fields, system.has_removed_table_rows, system.requires_table_field_replacement und der Änderungsverfolgung.
Wurden keine Felder geändert und keine Dateien übergeben, wird der Server-Aufruf standardmäßig übersprungen. Mit force=True kann der Aufruf erzwungen werden.
Wird die aktualisierte Instanz direkt nach dem Speichern benötigt, ist update_and_get() die kompaktere Alternative.
1. Signatur
-
Sync
-
Async
ecm.dms.update(
model: T,
files: list[JobRequestFile] | None = None,
replace_files: bool = True,
force: bool = False,
*,
check_mandatory: bool = True,
) -> None
await ecm.dms.update(
model: T,
files: list[JobRequestFile] | None = None,
replace_files: bool = True,
force: bool = False,
*,
check_mandatory: bool = True,
) -> None
2. Parameter
| Name | Typ | Beschreibung |
|---|---|---|
|
|
Die zu aktualisierende Modell-Instanz. Muss vom Server geladen worden sein, damit |
|
|
Optionale Dateiliste für das Dokument. Nur für |
|
|
Wenn |
|
|
Wenn |
|
|
Wenn |
4. Automatisches Überspringen
Wenn alle der folgenden Bedingungen zutreffen, wird der Server-Aufruf ohne Fehler übersprungen:
-
force=False(Standard) -
model.system.is_modifiedistFalse— keine Felder wurden geändert -
filesistNone
Das Änderungsprotokoll (is_modified, modified_fields, modified_table_fields) wird vom Modell automatisch beim Setzen von Feldwerten geführt. Nur diese tatsächlich geänderten Felder werden serialisiert — unveränderte Felder bleiben dem Server fern und werden nicht überschrieben.
Tabellenfelder werden differenziert behandelt:
-
Wurde eine geladene Zeile verändert, entfernt oder ersetzt (d. h.
system.requires_table_field_replacementistTrue), wird das Tabellenfeld komplett neu übertragen und der Server-Aufruf erhält automatischREPLACETABLEFIELDS=1, sodass der Server die gesamte Tabelle ersetzt. -
Wurden nur neue Zeilen angefügt, werden ausschließlich diese neuen Zeilen übertragen — der Server-Default „APPEND" verhindert Duplikate der geladenen Zeilen.
-
Tabellenfelder ohne Änderung werden gar nicht in der XML aufgenommen und bleiben serverseitig unangetastet.
5. Schreibbare Systemfelder
Systemfelder (SystemFields-Enum) werden standardmäßig aus der dms.XMLUpdate-XML herausgefiltert, da der enaio-Server fast alle mit ECMAccessDeniedException („The specified system field cannot be changed by the user") ablehnt. Eine Allowlist WRITABLE_SYSTEM_FIELDS (in ecmind_blue_client.const) listet die wenigen Felder, die der Server tatsächlich akzeptiert:
| Feld | Verhalten |
|---|---|
|
String-Feld. Insert + Update. Hält die Referenz auf das Dokument im externen Archivsystem; in Kombination mit |
|
Int-Feld. Nur Update. Beim Insert verlangt der Server, dass |
|
String-Feld (Owner). Insert + Update. Der Wert muss der Benutzername sein (z. B. |
Nicht über <Field> verfügbar, sondern als XML-Attribute auf <Object>/<ObjectType> gepflegt und über andere APIs (z. B. insert(), move()) gesteuert: OBJECT_MAIN (= maintype), OBJECT_CO (= cotype), OBJECT_ID (= object_id), SDSTA_ID/SDREG_ID/FOLDERID/REGISTERID/… (= folder_id/register_id/…). Diese liefern als <Field> ebenfalls ECMAccessDeniedException zurück.
Weitere bislang nicht entdeckte schreibbare Systemfelder können nachträglich in WRITABLE_SYSTEM_FIELDS ergänzt werden, ohne Modelländerungen.
from ecmind_blue_client import WRITABLE_SYSTEM_FIELDS
# Programmatisch erweitern (Run-time; persistiert nicht):
WRITABLE_SYSTEM_FIELDS.add("OBJECT_AVID")
6. Ausnahmen
ValueError-
model.system.idistNone(Objekt wurde nicht vom Server geladen) odercheck_mandatory=Trueund ein Pflichtfeld ist nicht gesetzt, oder ein schreibgeschütztes Feld (ECMField(read_only=…)) wurde geändert — siehe ECM-Modell. TypeError-
fileswurde für ein Ordner- oder Register-Modell übergeben.
7. Beispiele
7.1. Einfaches Feldupdate
-
Sync
-
Async
folder = ecm.dms.get(InvoiceFolder, 12345)
folder.Title = "Rechnung 2024 (aktualisiert)"
ecm.dms.update(folder)
folder = await ecm.dms.get(InvoiceFolder, 12345)
folder.Title = "Rechnung 2024 (aktualisiert)"
await ecm.dms.update(folder)
7.2. Dokument mit Datei ersetzen
-
Sync
-
Async
from ecmind_blue_client.rpc import JobRequestFileFromPath
doc = ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (korrigiert)"
ecm.dms.update(
doc,
files=[JobRequestFileFromPath("/tmp/rechnung_v2.pdf")],
replace_files=True, # vorhandene Dateien ersetzen (Standard)
)
from ecmind_blue_client.rpc import JobRequestFileFromPath
doc = await ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Rechnung Nr. 42 (korrigiert)"
await ecm.dms.update(
doc,
files=[JobRequestFileFromPath("/tmp/rechnung_v2.pdf")],
replace_files=True,
)
7.3. Datei anhängen statt ersetzen
-
Sync
-
Async
from ecmind_blue_client.rpc import JobRequestFileFromPath
doc = ecm.dms.get(InvoiceDocument, 42)
ecm.dms.update(
doc,
files=[JobRequestFileFromPath("/tmp/anhang.pdf")],
replace_files=False, # Datei hinzufügen, bestehende behalten
)
from ecmind_blue_client.rpc import JobRequestFileFromPath
doc = await ecm.dms.get(InvoiceDocument, 42)
await ecm.dms.update(
doc,
files=[JobRequestFileFromPath("/tmp/anhang.pdf")],
replace_files=False,
)
7.4. Update erzwingen
Nützlich, wenn externe Logik eine Neuübermittlung erfordert, obwohl keine Felder geändert wurden:
-
Sync
-
Async
folder = ecm.dms.get(InvoiceFolder, 12345)
# keine Feldänderung — ohne force=True würde der Aufruf übersprungen
ecm.dms.update(folder, force=True)
folder = await ecm.dms.get(InvoiceFolder, 12345)
await ecm.dms.update(folder, force=True)
7.5. Pflichtfeldprüfung deaktivieren
-
Sync
-
Async
folder = ecm.dms.get(InvoiceFolder, 12345)
folder.Title = None # Pflichtfeld leeren
# check_mandatory=False: kein Fehler, Pflichtfeldprüfung auch serverseitig deaktiviert
ecm.dms.update(folder, check_mandatory=False)
folder = await ecm.dms.get(InvoiceFolder, 12345)
folder.Title = None
await ecm.dms.update(folder, check_mandatory=False)
8. Siehe auch
-
update_and_get() — kombiniert
update()undget()in einem Aufruf, wenn die aktualisierte Instanz benötigt wird -
insert() — legt ein neues Objekt an
-
get() — lädt ein einzelnes Objekt vom Server