insert()

Creates a new object on the server and returns (object_id, object_type_id). Internally uses dms.XMLInsert. The passed model instance is not mutated.

If the fully populated instance is needed directly after creation, insert_and_get() is the more compact alternative.

1. Signature

  • Sync

  • Async

ecm.dms.insert(
    model: T,
    files: Sequence[JobRequestFile] | None = None,
    *,
    folder_id: int | str | ECMFolderModel | None = None,
    register_id: int | str | ECMRegisterModel | None = None,
    check_mandatory: bool = True,
    options: ECMInsertOptions | None = None,
) -> tuple[int, int]
await ecm.dms.insert(
    model: T,
    files: Sequence[JobRequestFile] | None = None,
    *,
    folder_id: int | str | ECMFolderModel | None = None,
    register_id: int | str | ECMRegisterModel | None = None,
    check_mandatory: bool = True,
    options: ECMInsertOptions | None = None,
) -> tuple[int, int]

2. Parameters

Name Type Description

model

ECMFolderModel | ECMRegisterModel | ECMDocumentModel

The model instance to create, with the desired field values set. The instance is not mutated.

files

Sequence[JobRequestFile] | None

Optional list of files to attach to the new document. Only allowed for ECMDocumentModel — raises TypeError for folder or register models. Default: None.

folder_id

int | str | ECMFolderModel | None

Folder to place the object in — either a numeric ID or an ECMFolderModel instance (its id is used). Only valid for registers and documents. Default: None.

register_id

int | str | ECMRegisterModel | None

Register to file the document in (ECMDocumentModel) or parent register (ECMRegisterModel) — either a numeric ID or an ECMRegisterModel instance. Default: None.

check_mandatory

bool

When True (default), validates client-side that all mandatory=True ECMField descriptors have a value. When False, both client-side and server-side obligation checks are disabled (CHECKOBLIGATION=0).

options

ECMInsertOptions | None

Additional dms.XMLInsert job options, e.g. ECMInsertOptions().init_fields(False).check_key_fields(False). Options set here take precedence over the ones derived from the typed parameters above. See Job options. Default: None.

3. Return value

tuple[int, int] — (object_id, object_type_id) of the newly created object.

4. Writable system fields

System fields (SystemFields enum) are stripped from the dms.XMLInsert payload by default; the enaio server rejects almost all of them with ECMAccessDeniedException. The allowlist WRITABLE_SYSTEM_FIELDS (in ecmind_blue_client.const) names those that the server accepts:

  • OBJECT_FOREIGNID — string field; reference into the external archive or the enaio object ID for a green arrow.

  • OBJECT_SYSTEMID — int field; on insert only accepted together with OBJECT_FOREIGNID in the same request (otherwise server error -1013).

  • OBJECT_USERGUID — owner; the value must be the target user’s username (e.g. "ROOT"), not the GUID hex. The server resolves and stores the GUID.

Details and examples in update().

5. Inserting a loaded model

A model loaded from the server can be passed to insert() as is, for instance to copy an object. All loaded index and table fields are sent. The owner only goes out as a user name: the server returns it as a GUID but rejects a GUID with error -1019. A GUID, loaded or copied via to_dict(), is therefore left out, and the new object belongs to the calling user; system.assign_owner() sets another owner (#15523). Fields a query did not request with fields() get the server’s initial values.

source = ecm.dms.get(InvoiceFolder, 12345)
source.system.assign_owner("MUELLER")   # optional, otherwise the copy belongs to the caller
new_id, _ = ecm.dms.insert(source)

6. Exceptions

ECMException

The server rejected the insert (ObjectID == -1).

ECMMissingArgumentException

folder_id is missing for a register or document model. Subclass of ECMException.

TypeError

files was provided for a folder or register model.

ValueError

check_mandatory=True and a required field is not set, or a read-only field (ECMField(read_only=…)) is written — see ECM model.

7. Examples

7.1. Simple folder

  • Sync

  • Async

object_id, object_type_id = ecm.dms.insert(
    InvoiceFolder(Title="Invoice 2024", Year=2024)
)
print(object_id)
object_id, object_type_id = await ecm.dms.insert(
    InvoiceFolder(Title="Invoice 2024", Year=2024)
)
print(object_id)

7.2. Register inside a folder

  • Sync

  • Async

object_id, _ = ecm.dms.insert(
    InvoiceRegister(Name="Incoming invoices"),
    folder_id=folder.system.id,
)
object_id, _ = await ecm.dms.insert(
    InvoiceRegister(Name="Incoming invoices"),
    folder_id=folder.system.id,
)

7.3. Document with file and filing location

  • Sync

  • Async

from ecmind_blue_client.rpc import JobRequestFileFromPath

object_id, _ = ecm.dms.insert(
    InvoiceDocument(Title="Invoice No. 42"),
    files=[JobRequestFileFromPath("/tmp/invoice.pdf")],
    folder_id=folder.system.id,
    register_id=register.system.id,
)
print(object_id)
from ecmind_blue_client.rpc import JobRequestFileFromPath

object_id, _ = await ecm.dms.insert(
    InvoiceDocument(Title="Invoice No. 42"),
    files=[JobRequestFileFromPath("/tmp/invoice.pdf")],
    folder_id=folder.system.id,
    register_id=register.system.id,
)
print(object_id)

7.4. Passing model instances as folder_id / register_id

Instead of a numeric ID, a model instance can be passed directly — insert() extracts the ID automatically:

  • Sync

  • Async

folder = ecm.dms.insert_and_get(InvoiceFolder(Title="Invoice 2024"))
register = ecm.dms.insert_and_get(
    InvoiceRegister(Name="Incoming"),
    folder_id=folder,          # ECMFolderModel instance instead of int
)
object_id, _ = ecm.dms.insert(
    InvoiceDocument(Title="Invoice No. 42"),
    folder_id=folder,          # ECMFolderModel instance
    register_id=register,      # ECMRegisterModel instance
)
folder = await ecm.dms.insert_and_get(InvoiceFolder(Title="Invoice 2024"))
register = await ecm.dms.insert_and_get(
    InvoiceRegister(Name="Incoming"),
    folder_id=folder,
)
object_id, _ = await ecm.dms.insert(
    InvoiceDocument(Title="Invoice No. 42"),
    folder_id=folder,
    register_id=register,
)

7.5. Disabling mandatory field validation

  • Sync

  • Async

# check_mandatory=False: no error even if required fields are missing
object_id, _ = ecm.dms.insert(
    InvoiceFolder(Title="Draft"),
    check_mandatory=False,
)
object_id, _ = await ecm.dms.insert(
    InvoiceFolder(Title="Draft"),
    check_mandatory=False,
)

7.6. Job options: object type with key fields

When the object type has server-side key fields, the server fills unset fields with their initial values on insert and checks the key fields for uniqueness. An import that already carries those values fails on exactly that. Both checks can be turned off per call:

  • Sync

  • Async

from ecmind_blue_client.ecm import ECMInsertOptions

# The invoice number is a key field of the type and supplied by the import itself
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),
)

Options from options take precedence over the ones derived from the typed parameters, so check_mandatory=False together with check_obligation(True) skips the client-side mandatory check while leaving the server-side one active.

Full option list in Job options.

8. See also

  • insert_and_get() — combines insert() and get() in one call when the full instance is needed immediately

  • update() — updates an existing object