upsert()
upsert() gibt einen fluenten Builder zurück, der dms.XMLImport kapselt.
Der Server führt zuerst eine Suche anhand der mit .search() konfigurierten Bedingungen durch und
führt je nach Trefferzahl die konfigurierte Aktion aus.
1. Signatur
-
Sync
-
Async
ecm.dms.upsert(
model: T,
folder_id: int | None = None,
register_id: int | None = None,
*,
check_mandatory: bool = True,
) -> ECMModelUpsertSync[T]
ecm.dms.upsert(
model: T,
folder_id: int | None = None,
register_id: int | None = None,
*,
check_mandatory: bool = True,
) -> ECMModelUpsertAsync[T]
2. Parameter
| Parameter | Standard | Beschreibung |
|---|---|---|
|
— |
Befüllte Modell-Instanz (Subklasse von |
|
|
ID des übergeordneten Ordners. Nur für |
|
|
ID des übergeordneten Registers. Bei |
|
|
Prüft beim Aufruf von |
3. Builder-Methoden
3.1. .search(*conditions)
Definiert die Suchbedingungen für die serverseitige Duplikatprüfung.
|
Nur |
.search(InvoiceFolder.Title == "Rechnung 2024", InvoiceFolder.Year == 2024)
3.2. .action0(value), .action1(value), .action_multiple(value)
Konfiguriert die Aktion abhängig von der Trefferzahl der Suche:
| Methode | Trefferanzahl | Standard | Gültige Werte |
|---|---|---|---|
|
0 Treffer |
|
|
|
genau 1 Treffer |
|
|
|
mehr als 1 Treffer |
|
|
Bedeutung der Aktionswerte:
"INSERT"-
Legt ein neues Objekt an.
"UPDATE"-
Aktualisiert das gefundene Objekt mit den Feldern aus
model. "NONE"-
Führt keine Aktion aus.
object_idundobject_type_idsind-1. "ERROR"-
Bricht mit einem Fehler ab.
3.3. .files(value, replace=True)
Hängt Dateien an den Upsert-Vorgang an. Nur für ECMDocumentModel gültig.
| Parameter | Standard | Beschreibung |
|---|---|---|
|
— |
|
|
|
Bei |
|
Wird |
3.4. .replace_table_fields(value=True)
Steuert, wie Tabellenfeld-Zeilen geschrieben werden, wenn der Upsert eine Aktualisierung durchführt. Standardmäßig hängt der Server die übergebenen Tabellenzeilen an die bereits gespeicherten an. Mit .replace_table_fields(True) wird stattdessen REPLACETABLEFIELDS=1 gesetzt, sodass die übergebenen Zeilen die vorhandenen ersetzen.
| Parameter | Standard | Beschreibung |
|---|---|---|
|
|
|
|
Die Option wirkt nur im Aktualisierungszweig des Upserts (Suche trifft genau ein Objekt und |
3.5. .execute()
Führt den Upsert aus und gibt ein 4-Tupel zurück:
| Element | Typ | Beschreibung |
|---|---|---|
|
|
ID des angelegten oder aktualisierten Objekts. |
|
|
Typ-ID des Objekts. |
|
|
Anzahl der vom Server gefundenen Treffer. |
|
|
Tatsächlich ausgeführte Aktion: |
3.6. .execute_and_get(…)
Führt den Upsert aus und lädt anschließend das resultierende Objekt vollständig vom Server nach —
das Builder-Pendant zu insert_and_get() und
update_and_get(). Gibt die typisierte Modell-Instanz statt des
(id, type_id, hits, action)-Tupels zurück. hits und action werden dabei verworfen; werden sie
benötigt, .execute() verwenden und selbst mit dms.get() nachladen.
.execute_and_get(
*,
rights: bool = False,
base_params: bool = False,
file_properties: bool = False,
variants: bool = False,
use_result_list: bool = False,
fields: list[str | ECMField] | None = None,
) -> T
Die Parameter werden an dms.get() durchgereicht (siehe dort für Details).
|
Liefert der Upsert kein verwendbares Objekt ( |
4. Ausnahmen
ValueError-
Ein Pflichtfeld hat keinen Wert und
check_mandatory=True, oder ein schreibgeschütztes Feld (ECMField(read_only=…)) wird geschrieben — siehe ECM-Modell. TypeError-
.files()wurde für ein Nicht-ECMDocumentModelaufgerufen. ECMException-
.execute_and_get()wurde aufgerufen, der Upsert lieferte aber kein verwendbares Objekt (object_id < 0).
5. Beispiele
5.1. Einfacher Folder-Upsert
Legt einen Ordner an oder aktualisiert ihn, falls er bereits existiert:
-
Sync
-
Async
object_id, type_id, hits, action = (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.execute()
)
print(action) # "INSERT" oder "UPDATE"
object_id, type_id, hits, action = await (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.execute()
)
print(action) # "INSERT" oder "UPDATE"
5.2. Nur anlegen, nicht aktualisieren
Mit action1("NONE") wird bei einem vorhandenen Treffer keine Aktion ausgeführt:
-
Sync
-
Async
object_id, type_id, hits, action = (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.action1("NONE")
.execute()
)
object_id, type_id, hits, action = await (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.action1("NONE")
.execute()
)
5.3. Register mit Standortangabe
-
Sync
-
Async
object_id, type_id, hits, action = (
ecm.dms.upsert(
InvoiceRegister(Name="2024"),
folder_id=42,
)
.search(InvoiceRegister.Name == "2024")
.execute()
)
object_id, type_id, hits, action = await (
ecm.dms.upsert(
InvoiceRegister(Name="2024"),
folder_id=42,
)
.search(InvoiceRegister.Name == "2024")
.execute()
)
5.4. Dokument mit Datei-Anhang
-
Sync
-
Async
from datetime import date
from ecmind_blue_client.rpc import JobRequestFile
object_id, type_id, hits, action = (
ecm.dms.upsert(
InvoiceDocument(Title="Rechnung 2024", InvoiceDate=date(2024, 3, 1)),
folder_id=42,
)
.search(InvoiceDocument.Title == "Rechnung 2024")
.files([JobRequestFile("rechnung.pdf", pdf_bytes)], replace=True)
.execute()
)
from datetime import date
from ecmind_blue_client.rpc import JobRequestFile
object_id, type_id, hits, action = await (
ecm.dms.upsert(
InvoiceDocument(Title="Rechnung 2024", InvoiceDate=date(2024, 3, 1)),
folder_id=42,
)
.search(InvoiceDocument.Title == "Rechnung 2024")
.files([JobRequestFile("rechnung.pdf", pdf_bytes)], replace=True)
.execute()
)
5.5. Pflichtfeldprüfung deaktivieren
-
Sync
-
Async
object_id, type_id, hits, action = (
ecm.dms.upsert(
InvoiceFolder(Year=2024),
check_mandatory=False,
)
.search(InvoiceFolder.Year == 2024)
.execute()
)
object_id, type_id, hits, action = await (
ecm.dms.upsert(
InvoiceFolder(Year=2024),
check_mandatory=False,
)
.search(InvoiceFolder.Year == 2024)
.execute()
)
5.6. Upsert und Objekt direkt zurückerhalten
Statt .execute() (Tupel) liefert .execute_and_get() die fertig befüllte Modell-Instanz:
-
Sync
-
Async
folder = (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.execute_and_get()
)
print(folder.id, folder.Title)
folder = await (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.execute_and_get()
)
print(folder.id, folder.Title)