objects_by_digest()

Sucht über dms.GetObjectsByDigest alle Dokumente, deren Dateien auf den angegebenen Digest hashen.

Das ist die serverseitige Hälfte der Duplikatprüfung: calculate_digest() macht aus lokalen Dateien den enaio-Digest, ohne sie hochzuladen, und diese Methode beantwortet die Frage, ob ein Dokument mit genau diesen Dateien bereits abgelegt ist. (Ticket #16111)

Der Job schlägt den Wert in osdochash nach (intern über std.FindDocumentDigest) und prüft anschliessend, ob die gefundenen Objekte noch existieren und für den aktuellen Benutzer sichtbar sind.

1. Signatur

  • Sync

  • Async

ecm.dms.objects_by_digest(digest: str) -> list[ECMDigestHit]
await ecm.dms.objects_by_digest(digest: str) -> list[ECMDigestHit]

2. Parameter

Parameter Typ Standard Beschreibung

digest

str

—

Der gesuchte Dokument-Digest, wie ihn calculate_digest() liefert oder wie er als table_digest aus digest() kommt. Gross- und Kleinschreibung sind egal.

3. Rückgabewert

Eine Liste von ECMDigestHit-Objekten, in der Reihenfolge, in der der Server sie aufgelistet hat. Leer, wenn nichts gefunden wurde.

Mehrere Dokumente können denselben Digest haben: dieselbe Datei zweimal archiviert ergibt zwei Treffer. Versionen werden nicht berücksichtigt.

3.1. Felder von ECMDigestHit

Feld Typ Beschreibung

id

int

Numerische ID des gefundenen Dokuments — genau das, was get() erwartet.

type_id

int

Numerische Objekttyp-ID. Der Server kodiert darin beides: (maintype << 16) | cotype.

main_type

ECMMainType | None

Der aus type_id dekodierte Grundtyp, z. B. ECMMainType.DOC_WINDOWS. None, wenn der Server einen dem Client unbekannten Grundtyp meldet — id und type_id bleiben in dem Fall uneingeschränkt nutzbar.

cotype

int

Der aus type_id dekodierte Cotype (untere 16 Bit).

ECMDigestHit ist eingefroren (frozen=True) und wird über from ecmind_blue_client.ecm import ECMDigestHit importiert.

4. Ausnahmen

Ausnahme Bedingung

ValueError

digest ist leer oder besteht nur aus Leerzeichen. Der Server würde darauf "keine Treffer" antworten, was sich nicht von einem echten Nicht-Treffer unterscheiden lässt und den Fehler verdeckt.

ECMException

Die beiden parallelen Ergebnislisten des Servers passen nicht zusammen oder decken sich nicht mit TotalHits.

5. Beispiele

5.1. Upload überspringen, wenn die Datei schon da ist

  • Sync

  • Async

hits = ecm.dms.objects_by_digest(ecm.dms.calculate_digest("rechnung.pdf"))
if hits:
    print(f"bereits abgelegt als {hits[0].id} ({hits[0].main_type})")
else:
    ecm.dms.insert(RechnungsDokument(Titel="Rechnung"), files=[RequestFileFromPath("rechnung.pdf")])
hits = await ecm.dms.objects_by_digest(await ecm.dms.calculate_digest("rechnung.pdf"))
if hits:
    print(f"bereits abgelegt als {hits[0].id} ({hits[0].main_type})")
else:
    await ecm.dms.insert(RechnungsDokument(Titel="Rechnung"), files=[RequestFileFromPath("rechnung.pdf")])

5.2. Gefundene Dokumente laden

for hit in ecm.dms.objects_by_digest(digest):
    doc = ecm.dms.get(RechnungsDokument, hit.id, hit.type_id)
    print(doc.system.id, doc.Titel)

5.3. Duplikate im Archiv finden

# Alle Dokumente, die dieselben Dateien haben wie ein bekanntes
hits = ecm.dms.objects_by_digest(ecm.dms.digest(doc).table_digest)
duplicates = [hit for hit in hits if hit.id != doc.system.id]

6. Siehe auch

  • calculate_digest() — den Digest lokal berechnen

  • digest() — den gespeicherten Digest eines Dokuments lesen

  • get() — ein gefundenes Objekt laden