Migration von der alten API
Diese Seite zeigt, wie die Methoden der veralteten abstrakten Client-Basisklasse (aus ecmind_blue_client.client) auf die aktuelle ECM-API umgestellt werden.
Die alte API basierte auf rohen Job-Objekten und untypisierten dict-Ergebnissen.
Die neue API nutzt typisierte Modellklassen, fluent Query Builder und strukturierte Exceptions.
1. Setup
-
Legacy
-
ECM API
from ecmind_blue_client.tcp_client import Connection
client = Connection(host, port, "App", user, password, ssl)
result = client.execute(job)
from ecmind_blue_client.pool import SyncPoolClient
from ecmind_blue_client.ecm import ECM
client = SyncPoolClient(servers="host:4000:1", username=user, password=password)
ecm = ECM(client)
Der SyncPoolClient verwaltet den Verbindungspool automatisch.
Für asyncio-Kontexte (FastAPI etc.) wird der AsyncPoolClient verwendet.
2. Methodenübersicht
2.1. lol_query() → ecm.dms.select_lol()
lol_query() führte paginierte Flachlisten-Abfragen (LOL) aus und lieferte untypisierte dict-Zeilen.
Das direkte Äquivalent in der neuen API ist ecm.dms.select_lol() — gleicher LOL-Format, aber mit typisierten Modellinstanzen.
-
Legacy
-
ECM API
from ecmind_blue_client.query_condition_group import QueryConditionGroup
results = list(client.lol_query(
"InvoiceFolder",
conditions=QueryConditionGroup("InvoiceFolder", [("Year", "=", "2024")]),
result_fields=["Title", "Year"],
page_size=100,
))
for row in results:
print(row["Title"], row["Year"])
from ecmind_blue_client.ecm.model import make_folder_model
InvoiceFolder = make_folder_model("InvoiceFolder")
for folder in ecm.dms.select_lol(InvoiceFolder).where(
InvoiceFolder["Year"] == 2024
).stream():
print(folder["Title"], folder["Year"])
Die neue API unterstützt zusätzlich hierarchische (HOL) Abfragen über ecm.dms.select().
HOL liefert reichere Objektgraphen mit Eltern-Kind-Beziehungen und ist für die meisten Anwendungsfälle die empfohlene Standardmethode.
|
Für statische Typprüfung empfiehlt sich die explizite Modelldeklaration statt make_folder_model:
from ecmind_blue_client.ecm.model import ECMFolderModel, ECMField
class InvoiceFolder(ECMFolderModel):
_internal_name_ = "InvoiceFolder"
Title: ECMField[str]
Year: ECMField[int]
# LOL — Flachliste, gleicher Aufbau wie lol_query()
for folder in ecm.dms.select_lol(InvoiceFolder).where(
InvoiceFolder.Year == 2024
).stream():
print(folder.Title, folder.Year)
# HOL — hierarchisch, für die meisten Abfragen empfohlen
for folder in ecm.dms.select(InvoiceFolder).where(
InvoiceFolder.Year == 2024
).order_by(InvoiceFolder.Year.DESC).stream():
print(folder.Title, folder.Year)
Siehe ecm.dms.select_lol() und ecm.dms.select().
2.2. xml_import() → ecm.dms.insert() / update() / upsert()
xml_import() kombinierte Insert- und Update-Logik über action0/action1-Parameter.
Die neue API trennt diese in klar benannte Methoden.
2.2.1. Insert
-
Legacy
-
ECM API
from ecmind_blue_client.const import ImportActions
client.xml_import(
"InvoiceFolder",
search_fields={},
import_fields={"Title": "Rechnung 2024", "Year": "2024"},
action0=ImportActions.INSERT,
action1=ImportActions.ERROR,
)
folder_id, type_id = ecm.dms.insert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
# oder Objekt direkt zurückgeben:
folder = ecm.dms.insert_and_get(InvoiceFolder(Title="Rechnung 2024", Year=2024))
2.2.2. Insert oder Update (Upsert)
-
Legacy
-
ECM API
from ecmind_blue_client.const import ImportActions
client.xml_import(
"InvoiceFolder",
search_fields={"Title": "Rechnung 2024"},
import_fields={"Year": "2024"},
action0=ImportActions.INSERT,
action1=ImportActions.UPDATE,
)
object_id, type_id, hits, action = (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.execute()
)
2.2.3. Mehrere Treffer (action_multiple)
Wenn die Suche mehr als ein übereinstimmendes Objekt findet, wird standardmäßig ein Fehler
zurückgegeben. Mit .action_multiple() kann dieser Fall explizit behandelt werden:
from ecmind_blue_client.const import ImportActions
object_id, type_id, hits, action = (
ecm.dms.upsert(InvoiceFolder(Title="Rechnung 2024", Year=2024))
.search(InvoiceFolder.Title == "Rechnung 2024")
.action_multiple(ImportActions.UPDATE) # alle Treffer aktualisieren
.execute()
)
Die Parameter main_type, variant_parent_id und options von xml_import() haben
kein direktes Äquivalent im High-Level-Upsert-Builder.
Für Operationen, die diese Parameter benötigen, steht ecm.execute() als
Low-Level-Escape-Hatch zur Verfügung.
|
2.3. get_object_details() → ecm.dms.get()
-
Legacy
-
ECM API
from ecmind_blue_client.const import SystemFields
details = client.get_object_details(
"InvoiceFolder",
object_id=42,
system_fields=[SystemFields.OBJECT_ID],
)
print(details["Title"])
folder = ecm.dms.get(InvoiceFolder, object_id=42)
print(folder.Title)
print(folder.system.id)
Siehe ecm.dms.get().
2.4. store_in_cache() / store_in_cache_by_id() → ecm.dms.files()
store_in_cache() und store_in_cache_by_id() lieferten rohe ResultFile-Objekte.
ecm.dms.files() vereint beide Methoden und gibt strukturierte Datei-Metadaten zurück.
-
Legacy
-
ECM API
files = client.store_in_cache(object_id=42)
for f in files:
data = f.bytes()
files = ecm.dms.files(document)
for f in files:
data = f.bytes()
2.4.1. Mit Dateikonvertierung (store_in_cache_by_id)
-
Legacy
-
ECM API
from ecmind_blue_client.const import StoreInCacheByIdConversion
files = client.store_in_cache_by_id(
object_id=42, convert=StoreInCacheByIdConversion.PDF
)
from ecmind_blue_client.const import StoreInCacheByIdConversion
files = ecm.dms.files(document, convert=StoreInCacheByIdConversion.PDF)
# oder per Objekt-ID:
files = ecm.dms.files(42, convert=StoreInCacheByIdConversion.PDF)
StoreInCacheByIdConversion unterstützt NONE (Standard), PDF (Haupttypen 1–4) und
MULTIPAGE_TIFF (TIFF-Haupttypen 2–3 werden zu einer einzigen Datei zusammengeführt).
Zusätzliche Parameter, die in der Legacy-API nicht vorhanden waren: when_cold_then_tiff
(COLD/ASCII-Dateien als TIFF zurückgeben) und add_annotations (Annotationen einbrennen).
Der checkout-Parameter von store_in_cache() hat kein Äquivalent in ecm.dms.files().
Für Checkout-Funktionalität kann ecm.execute() mit dem rohen Job verwendet werden.
|
Siehe ecm.dms.files().
2.5. get_object_type_by_id() → ecm.dms.get_object_type_by_id()
Beide APIs bieten diese Methode mit identischer Signatur.
-
Legacy
-
ECM API
type_id = client.get_object_type_by_id(object_id=42)
type_id = ecm.dms.get_object_type_by_id(object_id=42)
2.6. execute_sql() → ecm.db.select()
-
Legacy
-
ECM API
rows = client.execute_sql("SELECT * FROM invoices WHERE year = ?", 2024)
for row in rows:
print(row["id"], row["title"])
result = ecm.db.select("SELECT * FROM invoices WHERE year = ?", 2024)
for row in result.rows:
print(row["id"], row["title"])
Siehe ecm.db.select().
2.7. execute() — Low-Level-Escape-Hatch
Beide APIs behalten eine rohe execute()-Methode für Jobs, die noch nicht durch die High-Level-API abgedeckt werden.
-
Legacy
-
ECM API
from ecmind_blue_client import Job
result = client.execute(Job("krn.GetServerInfo", Flags=0, Info=6))
print(result.values["Value"])
from ecmind_blue_client.rpc import Jobs
result = ecm.execute(Jobs.KRN_GETSERVERINFO, Flags=0, Info=6)
print(result.values["Value"])
3. Benutzerwechsel (Context-User)
Die alte API übergab context_user als Parameter an einzelne Methoden.
Die neue API verwendet einen Context Manager, der den Benutzer in alle Operationen innerhalb des Blocks injiziert.
-
Legacy
-
ECM API
client.xml_import(..., context_user="john")
with ecm.impersonate("john") as ecm_john:
ecm_john.dms.insert(InvoiceFolder(Title="Rechnung 2024"))
4. Neue Funktionen in der ECM API
Die folgenden Methoden sind in ecm.dms verfügbar, haben aber kein Äquivalent in der
veralteten Client-Basisklasse.
4.1. Löschen, Verschieben, Kopieren
# Löschen (Soft-Delete standardmäßig; hard_delete=True umgeht den Papierkorb)
ecm.dms.delete(folder)
ecm.dms.delete(folder, hard_delete=True, delete_cascading=True)
# Dokument in ein anderes Register verschieben
ecm.dms.move(document, folder_id=target_folder, register_id=target_register)
# Ordner inklusive aller Kinder kopieren
ecm.dms.copy(folder, folder_id=target_folder, copy_cascading=True)
# Verknüpfte Kopie eines Dokuments erstellen (zweiter Ablagort, gemeinsamer Indexsatz)
ecm.dms.copy(document, folder_id=target_folder, register_id=target_register, link_document=True)
4.2. Erweiterte Abfrageoptionen (ecm.dms.select())
ecm.dms.select() bietet HOL-Abfragemodifikatoren ohne Legacy-Äquivalent:
# Rechte, Basisparameter und Datei-Metadaten in die Antwort einschließen
results = (
ecm.dms.select(InvoiceFolder)
.where(InvoiceFolder.Year == 2024)
.rights()
.base_params()
.execute()
)
# Hierarchische Traversierung
results = ecm.dms.select(InvoiceFolder).with_children().execute()
results = ecm.dms.select(InvoiceFolder).with_parents().execute()
# Dokumentvarianten einschließen
results = ecm.dms.select(InvoiceDocument).variants().execute()
# Papierkorb abfragen
results = ecm.dms.select(InvoiceFolder).garbage_mode().execute()