> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognite.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Understanding data modeling syncers

> Learn how Cognite Data Fusion (CDF) uses syncers to manage CogniteFile and CogniteTimeSeries data model concepts.

When you use the Cognite Core data model, `CogniteFile` and `CogniteTimeSeries` are two special concepts that represent files and time series. A **syncer** automatically keeps a corresponding asset-centric resource in sync whenever you create or update a node in either of these views.

## How syncers work

A concept in a data model is implemented as a view in CDF. A view contains properties that are either connections to other views or mappings to containers — the physical storage of data. See the [data modeling documentation](/cdf/dm/dm_concepts/dm_containers_views_datamodels) for more information about views and containers.

`CogniteTimeSeries` maps to `CogniteDescribable` (name, description, and similar properties), `CogniteSourceable` (source, sourceId, and similar properties), and `CogniteTimeSeries` (time series-specific properties such as type and step).

```mermaid theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
graph TD
    A[CogniteTimeSeries View] --> B[CogniteDescribable Container]
    A --> C[CogniteSourceable Container]
    A --> D[CogniteTimeSeries Container]

    B --> B1[Properties: name, description, etc.]
    C --> C1[Properties: source, sourceId, etc.]
    D --> D1[Properties: time series specific data]
```

`CogniteFile` maps to the same `CogniteDescribable` and `CogniteSourceable` containers, plus a `CogniteFile` container that holds file-specific properties.

```mermaid theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
graph TD
    A[CogniteFile View] --> B[CogniteDescribable Container]
    A --> C[CogniteSourceable Container]
    A --> D[CogniteFile Container]

    B --> B1[Properties: name, description, etc.]
    C --> C1[Properties: source, sourceId, etc.]
    D --> D1[Properties: file specific data]
```

When you create a node that has properties in either the `CogniteFile` or `CogniteTimeSeries` containers, a syncer automatically creates a corresponding file or time series resource in the asset-centric CDF API. This supports blob data storage for files and high-performance time series data storage.

## Example: Create and sync a time series

The following example uses the Python SDK. Files work in the same way.

First, create a `CogniteTimeSeries` node in data modeling:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> from cognite.client import CogniteClient
>>> from cognite.client.data_classes.data_modeling.cdm.v1 import CogniteTimeSeriesApply
>>> client = CogniteClient()
>>> my_cognite_timeseries = CogniteTimeSeriesApply(
...    space="demo_space",
...    external_id="my_cognite_timeseries",
...    is_step=False,
...    time_series_type="numeric",
...    name="My Cognite Time Series",
... )
>>> created_cognite_timeseries = client.data_modeling.instances.apply(my_cognite_timeseries).nodes[0]
>>> created_cognite_timeseries.dump()
{'space': 'demo_space',
 'instanceType': 'node',
 'externalId': 'my_cognite_timeseries',
 'version': 1,
 'wasModified': False,
 'lastUpdatedTime': 1762934508337,
 'createdTime': 1762934508337}
```

The syncer automatically creates a corresponding asset-centric time series resource in CDF:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> retrieve_asset_centric_timeseries = client.time_series.retrieve(instance_id=my_cognite_timeseries.as_id())
>>> retrieve_asset_centric_timeseries.dump()
{'instanceId': {'space': 'demo_space', 'externalId': 'my_cognite_timeseries'},
 'name': 'My Cognite Time Series',
 'isString': False,
 'metadata': {},
 'isStep': False,
 'securityCategories': [],
 'id': 4615119519582224,
 'createdTime': 1762934686780,
 'lastUpdatedTime': 1762934686780}
```

The following diagram illustrates how the syncer links the node to the asset-centric resource and its datapoints store:

```mermaid theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
graph LR
    A[CogniteTimeSeries Node<br/>space: demo_space<br/>externalId: my_cognite_timeseries] -->|Syncer creates| B[Asset-Centric TimeSeries<br/>id: 4615119519582224<br/>instanceId: demo_space/my_cognite_timeseries]
    B --> C[Datapoints Store<br/>timestamp: 1578006000000<br/>value: 3.0]
```

## Working with synced resources

### Inserting and retrieving datapoints

Insert datapoints using the `CogniteTimeSeries` instance ID:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> client.time_series.data.insert(
...    datapoints=[
...        {"timestamp": 1577833200000, "value": 1.0},
...        {"timestamp": 1577919600000, "value": 2.0},
...        {"timestamp": 1578006000000, "value": 3.0},
...    ],
...    instance_id=my_cognite_timeseries.as_id(),
... )
```

Retrieve datapoints using the instance ID:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> last_datapoint_instance_id = client.time_series.data.retrieve_latest(instance_id=my_cognite_timeseries.as_id())
>>> last_datapoint_instance_id.dump()
{'id': 4615119519582224,
 'isString': False,
 'isStep': False,
 'instanceId': {'space': 'demo_space', 'externalId': 'my_cognite_timeseries'},
 'datapoints': [{'timestamp': 1578006000000, 'value': 3.0}]}
```

Alternatively, use the internal `id` from the asset-centric time series the syncer created:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> last_datapoint_id = client.time_series.data.retrieve_latest(id=retrieve_asset_centric_timeseries.id)
>>> last_datapoint_id.dump()
{'id': 4615119519582224,
 'isString': False,
 'isStep': False,
 'instanceId': {'space': 'demo_space', 'externalId': 'my_cognite_timeseries'},
 'datapoints': [{'timestamp': 1578006000000, 'value': 3.0}]}
```

### Deletion and modification restrictions

The asset-centric time series is linked to the `CogniteTimeSeries` node and cannot be deleted or modified outside of data modeling.

Attempting to delete through the asset-centric API returns an error:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> from cognite.client.exceptions import CogniteAPIError
>>> try:
...     client.time_series.delete(retrieve_asset_centric_timeseries.id)
... except CogniteAPIError as e:
...     print(e.message)
Time series with instance ids must be deleted through data modeling
```

Attempting to modify a DM-controlled property also returns an error:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> from cognite.client.data_classes import TimeSeriesUpdate
>>> try:
...     client.time_series.update(TimeSeriesUpdate(id=retrieve_asset_centric_timeseries.id).name.set("New name"))
... except CogniteAPIError as e:
...     print(e.message)
Field 'name' on a time series with instance id can only be updated through the models/instances endpoint
```

The following properties have no representation in data modeling and can still be modified through the asset-centric API:

* `externalId`
* `metadata`
* `assetId`
* `dataSetId`

### Updating properties through data modeling

To update a DM-controlled property such as `name`, use the data modeling instances endpoint:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> from cognite.client.data_classes.data_modeling import NodeApply, NodeOrEdgeData, ViewId
>>> update = NodeApply(
...     space=my_cognite_timeseries.space,
...     external_id=my_cognite_timeseries.external_id,
...     sources=[
...         NodeOrEdgeData(
...             source=ViewId("cdf_cdm", "CogniteTimeSeries", "v1"),
...             properties={"name": "New CogniteTimeSeriesName"}
...         )
...     ]
... )
>>> updated_node = client.data_modeling.instances.apply(update).nodes[0]
>>> updated_node.dump()
{'space': 'demo_space',
 'instanceType': 'node',
 'externalId': 'my_cognite_timeseries',
 'version': 2,
 'wasModified': True,
 'lastUpdatedTime': 1762936334576,
 'createdTime': 1762934508337}
```

When you retrieve the asset-centric time series again, the name reflects the update:

```python theme={"languages":{"custom":["/_languages/kuiper.json","../_languages/kuiper.json"]}}
>>> updated_asset_centric_timeseries = client.time_series.retrieve(id=retrieve_asset_centric_timeseries.id)
>>> updated_asset_centric_timeseries.dump()
{'instanceId': {'space': 'demo_space', 'externalId': 'my_cognite_timeseries'},
 'name': 'New CogniteTimeSeriesName',
 'isString': False,
 'metadata': {},
 'isStep': False,
 'securityCategories': [],
 'id': 4615119519582224,
 'createdTime': 1762934686780,
 'lastUpdatedTime': 1762936334821}
```

## Further reading

* [Migrating files and time series](/cdf/deploy/cdf_toolkit/guides/plugins/migration_plugin/files_timeseries)
* [Migration overview](/cdf/deploy/cdf_toolkit/guides/plugins/migration_plugin/steps)
