

# Criar um trabalho OData no SAP
<a name="sap-odata-creating-job"></a>

Consulte [Criar trabalhos de ETL visuais com o AWS Glue Studio](https://docs.aws.amazon.com/glue/latest/dg/author-job-glue.html)

# Fontes de Provisionamento de Dados Operacionais (ODP)
<a name="sap-odata-operational-data-provisioning-sources"></a>

O Provisionamento de Dados Operacionais (ODP) oferece uma infraestrutura técnica que você pode usar para dar suporte à extração e à replicação de dados para várias aplicações de destino e que é compatível com mecanismos delta nesses cenários. No caso de um procedimento delta, os dados de uma fonte (Provedor ODP) são automaticamente gravados em uma fila delta (Fila Delta Operacional, ODQ) usando um processo de atualização ou passados para a fila delta usando uma interface de extração. Um provedor ODP pode ser um DataSource (extratores), visualizações do ABAP Core Data Services (Visualizações do ABAP CDS), SAP BW ou SAP BW/4HANA, SAP Landscape Transformation Replication Server (SLT) e SAP HANA Information Views (visualizações de cálculo). As aplicações de destino (chamados de "assinantes" de ODQ ou, mais geralmente, "Consumidores de ODP") recuperam os dados da fila delta e continuam processando esses dados.

## Carga total
<a name="sap-odata-full-load"></a>

No contexto das entidades OData e ODP do SAP, uma **carga total** se refere ao processo de extrair todos os dados disponíveis de uma entidade ODP em uma única operação. Essa operação recupera todo o conjunto de dados do sistema de origem, garantindo que o sistema de destino tenha uma cópia abrangente e atualizada dos dados da entidade. As cargas totais geralmente são usadas para fontes que não são compatíveis com cargas incrementais ou quando é necessária uma atualização do sistema de destino.

**Exemplo**

Você pode definir explicitamente o sinalizador `ENABLE_CDC` como false ao criar o DynamicFrame. Observação: `ENABLE_CDC` é false por padrão. Se você não quiser inicializar a fila delta, não precisará enviar esse sinalizador nem defini-lo como true. Não definir esse sinalizador como true resultará na extração da carga total.

```
sapodata_df = glueContext.create_dynamic_frame.from_options(
    connection_type="SAPOData",
    connection_options={
        "connectionName": "connectionName",
        "ENTITY_NAME": "entityName",
        "ENABLE_CDC": "false"
    }, transformation_ctx=key)
```

## Carga incremental
<a name="sap-odata-incremental-load"></a>

Uma **carga incremental** no contexto das entidades ODP (Operational Data Provisioning) envolve a extração somente dos dados novos ou alterados (deltas) do sistema de origem desde a última extração de dados, evitando o pré-processamento dos registros já processados. Essa abordagem melhora significativamente a eficiência, reduz os volumes de transferência de dados, melhora a performanda, garante a sincronização entre os sistemas e minimiza o tempo de processamento, especialmente para grandes conjuntos de dados que mudam com frequência.

# Transferências incrementais baseadas no token delta
<a name="sap-odata-incremental-transfers"></a>

Para habilitar a transferência incremental usando Change Data Capture (CDC) para entidades habilitadas para ODP compatíveis, siga estas etapas:

1. Crie a tarefa de transferência incremental no modo de script.

1. Ao criar o DataFrame ou o DynamicFrame do Glue, você precisa passar a opção `"ENABLE_CDC": "True"`. Essa opção garante que você receberá um token delta da SAP, que poderá ser usado para subsequente recuperação dos dados alterados.

O token delta poderá ser encontrado na última linha do dataframe, na coluna DELTA\$1TOKEN. Você poderá usar esse token como uma opção de conector em chamadas subsequentes para recuperar o próximo conjunto de dados incrementalmente.

**Exemplo**
+ Definimos o sinalizador `ENABLE_CDC` como `true`, ao criar o DynamicFrame. Observação: `ENABLE_CDC` será `false` por padrão, se você não quiser inicializar a fila delta, não precisará enviar esse sinalizador nem defini-lo como true. Não definir esse sinalizador como true resultará na extração da carga total.

  ```
  sapodata_df = glueContext.create_dynamic_frame.from_options(
      connection_type="SAPOData",
      connection_options={
          "connectionName": "connectionName",
          "ENTITY_NAME": "entityName",
          "ENABLE_CDC": "true"
      }, transformation_ctx=key)
  
  # Extract the delta token from the last row of the DELTA_TOKEN column
  delta_token_1 = your_logic_to_extract_delta_token(sapodata_df) # e.g., D20241029164449_000370000
  ```
+ O token delta extraído pode ser passado como uma opção para recuperar novos eventos.

  ```
  sapodata_df_2 = glueContext.create_dynamic_frame.from_options(
      connection_type="SAPOData",
      connection_options={
          "connectionName": "connectionName",
          "ENTITY_NAME": "entityName",
          // passing the delta token retrieved in the last run
          "DELTA_TOKEN": delta_token_1
      } , transformation_ctx=key)
  
  # Extract the new delta token for the next run
  delta_token_2 = your_logic_to_extract_delta_token(sapodata_df_2)
  ```

Observe que o último registro, no qual o `DELTA_TOKEN` está presente, não é um registro transacional da fonte e existe apenas com a finalidade de passar o valor do token delta.

Além do `DELTA_TOKEN`, os campos a seguir são retornados em cada linha do dataframe. 
+ **GLUE\$1FETCH\$1SQ**: esse é um campo sequencial, gerado a partir do timestamp EPOC na ordem de recebimento dos registros e é exclusivo para cada registro. Isso pode ser usado se você precisar conhecer ou estabelecer a ordem das alterações no sistema de origem. Esse campo estará presente apenas para entidades habilitadas para ODP.
+ **DML\$1STATUS**: isso exibirá `UPDATED` para todos os registros recém-inseridos e atualizados a partir da fonte e `DELETED` para os registros que foram excluídos da fonte.

Para obter mais detalhes sobre como gerenciar estado e reutilizar o token delta para recuperar registros alterados por meio de um exemplo, consulte a seção [Uso do script de gerenciamento de estado do SAP OData](sap-odata-state-management-script.md).

## Invalidação do token delta
<a name="sap-odata-invalidation"></a>

Um token delta é associado ao conjunto de serviços e a um usuário. Se uma extração inicial com `“ENABLE_CDC” : “true”` for iniciada para o mesmo conjunto de serviços e usuário, todos os tokens delta anteriores emitidos como resultado de uma inicialização anterior serão invalidados pelo serviço OData do SAP. Invocar o conector com um token delta expirado gerará uma exceção: 

`Could not open data access via extraction API RODPS_REPL_ODP_OPEN` 

# Serviços OData (fontes não ODP)
<a name="sap-odata-non-odp-services"></a>

## Carga total
<a name="sap-odata-non-odp-full-load"></a>

Para sistemas não ODP (Operational Data Provisioning), uma **carga total** envolve extrair todo o conjunto de dados do sistema de origem e carregá-lo no sistema de destino. Como os sistemas não ODP não são inerantemente compatíveis com mecanismos avançados de extração de dados como deltas, o processo é simples, mas pode consumir muitos recursos, dependendo do tamanho dos dados.

## Carga incremental
<a name="sap-odata-non-odp-incremental-load"></a>

Para sistemas ou entidades que não são compatíveis com **ODP (Operational Data Provisioning)**, a transferência incremental de dados pode ser gerenciada manualmente por meio da implementação de um mecanismo baseado em timestamp para rastrear e extrair as alterações.

**Transferências incrementais baseadas em timestamp**

Para entidades não habilitadas para ODP (ou para entidades habilitadas para ODP que não usam o sinalizador ENABLE\$1CDC), você pode usar uma opção `filteringExpression` no conector para indicar o intervalo de `datetime` para o qual queremos recuperar dados. Esse método depende de um campo de timestamp nos dados, que mostra quando cada registro foi criado/modificado a última vez.

**Exemplo**

Recuperação de registros que foram alterados após 2024-01-01T00:00:00.000

```
sapodata_df = glueContext.create_dynamic_frame.from_options(
    connection_type="SAPOData",
    connection_options={
        "connectionName": "connectionName",
        "ENTITY_NAME": "entityName",
        "filteringExpression": "LastChangeDateTime >= 2024-01-01T00:00:00.000"
    }, transformation_ctx=key)
```

Nesse exemplo, `LastChangeDateTime` é o campo que representa quando cada registro foi modificado a última vez. O nome real do campo pode variar, dependendo da entidade específica do SAP OData.

Para obter um novo subconjunto de dados em execuções subsequentes, você pode atualizar o `filteringExpression` com um novo carimbo de data e hora. Normalmente, esse seria o valor máximo do carimbo de data e hora dos dados recuperados anteriormente.

**Exemplo**

```
max_timestamp = get_max_timestamp(sapodata_df)  # Function to get the max timestamp from the previous run
next_filtering_expression = f"LastChangeDateTime > {max_timestamp}"

# Use this next_filtering_expression in your next run
```

Na próxima seção, forneceremos uma abordagem automatizada para gerenciar essas transferências incrementais com base em carimbo de data e hora, eliminando a necessidade de atualizar manualmente a expressão de filtragem entre as execuções.