= update_and_get()
:description: Updates an ECM object (dms.XMLUpdate) and immediately reads back the full updated instance. Combines update() and get() in one call.
:keywords: update_and_get, XMLUpdate, instance, update, server fields, ECMFolderModel
:page-tags: api, dms

Combines xref:api/dms/update.adoc[update()] and xref:api/dms/get.adoc[get()] into a single call: updates an existing object and immediately returns the fully server-populated model instance.

`get()` is always executed — even if `update()` detected no changes and skipped the server call.

== Signature

[tabs]
====
Sync::
+
[source,python]
----
ecm.dms.update_and_get(
    model: T,
    files: list[JobRequestFile] | None = None,
    replace_files: bool = True,
    force: bool = False,
    *,
    check_mandatory: bool = True,
    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
----

Async::
+
[source,python]
----
await ecm.dms.update_and_get(
    model: T,
    files: list[JobRequestFile] | None = None,
    replace_files: bool = True,
    force: bool = False,
    *,
    check_mandatory: bool = True,
    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
----
====

== Parameters

=== Update parameters

[cols="1,1,3"]
|===
|Name |Type |Description

|`model`
|`ECMFolderModel \| ECMRegisterModel \| ECMDocumentModel`
|The model instance to update. Must have been loaded from the server so that `model.system.id` is set.

|`files`
|`list[JobRequestFile] \| None`
|Optional list of files for the document. Only allowed for `ECMDocumentModel` — raises `TypeError` for folder or register models. Default: `None`.

|`replace_files`
|`bool`
|When `True` (default) and `files` are provided, the new files replace the existing document files (`REPLACEFILES=1`). When `False`, files are appended to the existing ones.

|`force`
|`bool`
|When `True`, the update call is always executed even when no changes are detected. Default: `False`.

|`check_mandatory`
|`bool`
|When `True` (default), validates client-side that all mandatory fields are set. When `False`, both client-side and server-side obligation checks are disabled (`CHECKOBLIGATION=0`).
|===

=== Get parameters

The following parameters are forwarded unchanged to xref:api/dms/get.adoc[get()]. See the get() reference for full details and behaviour.

[cols="1,1,3"]
|===
|Name |Type |Summary

|`rights`
|`bool`
|Fetch access rights (`obj.system.rights`). Default: `False`.

|`base_params`
|`bool`
|Fetch administrative metadata (`obj.system.base_params`). Default: `False`.

|`file_properties`
|`bool`
|Fetch file metadata (`obj.system.file_properties`, documents only). Default: `False`.

|`variants`
|`bool`
|Fetch W-module version branches (`obj.system.variants`). Default: `False`.

|`use_result_list`
|`bool`
|Switch retrieval mode (enables `folder_id`/`register_id` in result). Default: `False`.

|`fields`
|`list[str \| ECMField] \| None`
|Restrict returned fields. Only effective with `use_result_list=True`. Default: `None`.
|===

== Return value

A typed model instance populated with all server-side field values (ID, system fields, index fields).

== Exceptions

`ValueError`:: `model.system.id` is `None` or `check_mandatory=True` and a required field is not set.
`TypeError`:: `files` was provided for a folder or register model.

== Examples

=== Simple field update

[tabs]
====
Sync::
+
[source,python]
----
folder = ecm.dms.get(InvoiceFolder, 12345)
folder.Title = "Invoice 2024 (updated)"
folder = ecm.dms.update_and_get(folder)
print(folder.system.id, folder.Title)
----

Async::
+
[source,python]
----
folder = await ecm.dms.get(InvoiceFolder, 12345)
folder.Title = "Invoice 2024 (updated)"
folder = await ecm.dms.update_and_get(folder)
print(folder.system.id, folder.Title)
----
====

=== Replace document file

[tabs]
====
Sync::
+
[source,python]
----
from ecmind_blue_client.rpc import JobRequestFileFromPath

doc = ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Invoice No. 42 (corrected)"
doc = ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/invoice_v2.pdf")],
)
----

Async::
+
[source,python]
----
from ecmind_blue_client.rpc import JobRequestFileFromPath

doc = await ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Invoice No. 42 (corrected)"
doc = await ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/invoice_v2.pdf")],
)
----
====

=== With metadata from get()

The `rights`, `base_params`, and `file_properties` parameters behave identically to xref:api/dms/get.adoc[get()]:

[tabs]
====
Sync::
+
[source,python]
----
doc = ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Invoice No. 42 (corrected)"
doc = ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/invoice_v2.pdf")],
    rights=True,
    base_params=True,
    file_properties=True,
)
print(doc.system.rights.edit_metadata)
print(doc.system.base_params.creator)
print(doc.system.file_properties.extension)
----

Async::
+
[source,python]
----
doc = await ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Invoice No. 42 (corrected)"
doc = await ecm.dms.update_and_get(
    doc,
    files=[JobRequestFileFromPath("/tmp/invoice_v2.pdf")],
    rights=True,
    base_params=True,
    file_properties=True,
)
print(doc.system.rights.edit_metadata)
print(doc.system.base_params.creator)
print(doc.system.file_properties.extension)
----
====

=== Read filing location from result (use_result_list)

`folder_id` and `register_id` in the result are only available with `use_result_list=True` — see xref:api/dms/get.adoc#_retrieval_modes[Retrieval modes in get()]:

[tabs]
====
Sync::
+
[source,python]
----
doc = ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Invoice No. 42 (updated)"
doc = ecm.dms.update_and_get(doc, use_result_list=True)
print(doc.system.folder_id)
print(doc.system.register_id)
----

Async::
+
[source,python]
----
doc = await ecm.dms.get(InvoiceDocument, 42)
doc.Title = "Invoice No. 42 (updated)"
doc = await ecm.dms.update_and_get(doc, use_result_list=True)
print(doc.system.folder_id)
print(doc.system.register_id)
----
====

== See also

* xref:api/dms/update.adoc[update()] — updates an object without returning it
* xref:api/dms/insert_and_get.adoc[insert_and_get()] — equivalent pattern for creating new objects
* xref:api/dms/get.adoc[get()] — loads a single object from the server
