Job options
Every dms.XML* server job accepts a semicolon-separated Options string such as INITFIELDS=0;CHECKKEYFIELDS=0. The option classes model those options in a typed way: one method per option, and each class offers only the options its job actually accepts.
The most common options are also available as dedicated parameters (check_mandatory, hard_delete, copy_cascading, …). The option objects complement those, they do not replace them.
1. Classes
| Class | Job | Used by |
|---|---|---|
|
|
insert(), insert_and_get(), insert_variant(), insert_variant_and_get() |
|
|
|
|
|
upsert() — the union of the insert and update sets, because |
|
|
|
|
|
|
|
|
2. Usage
The objects are immutable: every method returns a new object, so calls can be chained.
-
Sync
-
Async
from ecmind_blue_client.ecm import ECMInsertOptions
object_id, _ = ecm.dms.insert(
InvoiceDocument(Title="Invoice no. 42"),
folder_id=folder.system.id,
options=ECMInsertOptions().init_fields(False).check_key_fields(False),
)
from ecmind_blue_client.ecm import ECMInsertOptions
object_id, _ = await ecm.dms.insert(
InvoiceDocument(Title="Invoice no. 42"),
folder_id=folder.system.id,
options=ECMInsertOptions().init_fields(False).check_key_fields(False),
)
On the upsert builder it is a builder method:
from ecmind_blue_client.ecm import ECMUpsertOptions
object_id, type_id, hits, action = (
ecm.dms.upsert(InvoiceFolder(Title="Invoice 2024"))
.search(InvoiceFolder.Title == "Invoice 2024")
.options(ECMUpsertOptions().init_fields(False))
.execute()
)
3. Precedence
Options derived from the typed parameters and options from the option object are merged. On conflict the option object wins:
# check_mandatory=False would send CHECKOBLIGATION=0,
# the option object sets it back to 1.
ecm.dms.insert(model, check_mandatory=False, options=ECMInsertOptions().check_obligation(True))
# sent: CHECKOBLIGATION=1
That is how you skip the client-side mandatory check without also disabling the server-side one.
4. Worked example: import from a legacy system
The most common reason to reach for job options is an import that carries all values itself and therefore trips over the server’s automatic behaviour. Three things typically collide: the object type has key fields the server wants to initialise and check for uniqueness, catalog values show up that are not maintained yet, and individual strings are longer than the field length allows.
from ecmind_blue_client.ecm import ECMInsertOptions, ECMUpdateOptions
# Build once, reuse inside the loop: the objects are immutable.
IMPORT_INSERT = (
ECMInsertOptions()
.init_fields(False) # the import supplies the values itself
.check_key_fields(False) # the invoice number is a key field and already unique
.check_catalogue(False) # cost centres are not maintained in the catalog yet
.truncate_values(True) # truncate overlong legacy data instead of rejecting it
)
IMPORT_UPDATE = ECMUpdateOptions().check_catalogue(False).truncate_values(True)
for record in legacy_records:
hits = (
ecm.dms.select(InvoiceDocument)
.where(InvoiceDocument.InvoiceNumber == record.number)
.execute()
)
if hits:
doc = hits[0]
doc.Title = record.title
ecm.dms.update(doc, options=IMPORT_UPDATE)
else:
ecm.dms.insert(
InvoiceDocument(Title=record.title, InvoiceNumber=record.number),
folder_id=target_folder,
options=IMPORT_INSERT,
)
|
Every one of these options disables a check that exists for a reason. They belong in a deliberately scoped import or migration path, not in ordinary application code. |
5. Turning off key field handling only
When only the key field automation is in the way:
options=ECMInsertOptions().init_fields(False).check_key_fields(False)
6. Options without a dedicated method
Server options that have no method of their own (newly added ones, for instance) are set through raw():
ECMInsertOptions().raw("SOMENEWOPTION", True)
raw() applies no job scoping — the caller is responsible for passing an option the target job knows.
An existing option string can be taken over:
ECMInsertOptions.from_string("INITFIELDS=0;CHECKKEYFIELDS=0")