Introdução

OCI Data Flow é um serviço totalmente gerenciado para executar aplicações Apache Spark. O Data Flow é usado para processar arquivos grandes, streaming, operações de banco de dados, e você pode construir muitas aplicações com processamento altamente escalável. O Apache Spark pode escalar e usar máquinas em cluster para paralelizar trabalhos com configuração mínima.

Usando Apache Spark como um serviço gerenciado (Data Flow), você pode adicionar muitos serviços escaláveis para multiplicar o poder do processamento em nuvem e este tutorial mostra como usar:

  • Data Flow: Como serviço gerenciado para processamento
  • Apache Iceberg: Como formato de tabela moderna para data lakes
  • Object Storage: Como repositório de arquivos de baixo custo e escalável
  • Autonomous Database: Como camada de consumo analítico, permitindo consultar tabelas Iceberg diretamente via SQL de forma simples, segura e integrada ao ecossistema OCI.

Observação:Este material foi desenvolvido exclusivamente para fins educacionais e de demonstração. Ele fornece exemplos para experimentação em um ambiente controlado e não está pronto para uso em produção. As configurações e práticas de segurança apresentadas aqui podem não ser adequadas para cenários reais, onde as exigências costumam ser muito mais complexas e dinâmicas. Antes de aplicar qualquer técnica ou configuração em produção, é essencial realizar uma avaliação abrangente de segurança, incluindo controle de acesso, criptografia, monitoramento e conformidade, garantindo alinhamento com as políticas e padrões da sua organização. A segurança deve ser sempre prioridade ao migrar de um ambiente de laboratório para um ambiente real.

Objetivos

  • Demonstrar como processar e transformar dados em larga escala usando OCI Data Flow (Spark gerenciado).

  • Entender os benefícios do Apache Iceberg para data lakes modernos

  • Criar e manipular tabelas no formato Apache Iceberg diretamente sobre o OCI Object Storage, explorando seus benefícios (ACID, Time Travel, Schema Evolution).

  • Integrar o Autonomous Database para consulta SQL simplificada sobre os dados gravados no Iceberg, permitindo análise e consumo em ferramentas analíticas.

  • Mostrar, na prática, como conectar todas essas camadas para construir um data lakehouse moderno na OCI.

overview flow

Pré-requisitos

Introdução ao apache iceberg 

iceberg

 

O Apache Iceberg é um formato de tabela de código aberto, projetado para gerenciar grandes volumes de dados analíticos, que geralmente ficam armazenados em data lakes. Ele atua como uma camada de metadados sobre seus arquivos de dados (ex: Parquet ou Avro) no armazenamento de objetos (S3, GCS ou Object Storage), permitindo que você trate esses arquivos como se fossem uma tabela de banco de dados.
overview-iceberg-with-cloud-providers

 

Um dos objetivos do Iceberg é resolver os desafios de confiabilidade e desempenho que surgem ao trabalhar com dados massivos em data lakes, oferecendo características que antes eram exclusivas de bancos de dados tradicionais.

Conceitos Fundamentais Para entender como o Iceberg funciona, é crucial conhecer alguns de seus conceitos centrais:

Metadados (Metadata): O Iceberg não armazena os dados brutos, mas sim os metadados sobre eles. Essa camada de metadados é a “inteligência” do Iceberg, pois ela descreve onde os arquivos de dados estão, como eles estão particionados e a evolução do esquema. Isso permite que diferentes mecanismos de processamento (como Spark, Trino ou Flink) consultem a mesma tabela de forma consistente e eficiente.

Catálogo (Catalog): O catálogo é o ponto de entrada para todas as operações. Ele rastreia o estado atual de cada tabela, ou seja, onde encontrar o arquivo de metadados mais recente. O Iceberg é flexível e pode usar diferentes catálogos, como o Hive Metastore, um serviço baseado em arquivos ou até mesmo um catálogo nativo na nuvem.

Snapshots: Cada vez que uma tabela é alterada (por exemplo, ao adicionar novos dados ou excluir registros), o Iceberg cria um novo snapshot. Um snapshot é um registro imutável do estado da tabela em um determinado momento. Ele aponta para uma lista de manifestos que, por sua vez, aponta para os arquivos de dados. Essa arquitetura de snapshots permite recursos (Time Travel).

Listas e Arquivos de Manifesto: Cada snapshot aponta para uma ou mais listas de manifesto. Essas listas contêm referências a arquivos de manifesto, que são arquivos que listam os arquivos de dados (os arquivos Parquet ou Avro reais) que compõem a tabela. Isso permite que as ferramentas de consulta leiam apenas os arquivos necessários para uma operação específica, em vez de listar todos os arquivos do diretório, o que melhora muito o desempenho.

overview-icebergcredit image (https://iceberg.apache.org/spec/#goals)

 

Evolução de Esquema (Schema Evolution): O Iceberg lida de forma nativa com a evolução do esquema, permitindo adicionar, remover, renomear ou reordenar colunas sem precisar reescrever todos os dados. Isso simplifica drasticamente a manutenção de tabelas à medida que os requisitos de dados mudam ao longo do tempo.

Particionamento Oculto (Hidden Partitioning): Um dos recursos mais poderosos do Iceberg. Em vez de exigir que o usuário especifique a partição de cada consulta (WHERE year = 2024 AND month = 8), o Iceberg gerencia os detalhes de particionamento internamente. O usuário pode simplesmente escrever uma consulta com base nas colunas da tabela (WHERE event_date > ‘2024-01-01’) e o Iceberg se encarrega de encontrar e filtrar as partições corretas, otimizando a consulta automaticamente.

Por que o Iceberg é Importante? O Iceberg resolve uma série de problemas comuns dos data lakes tradicionais baseados em arquivos:

Transações ACID: Garante que as operações de escrita sejam atômicas. Ou seja, uma escrita completa ou falha por completo, sem deixar a tabela em um estado inconsistente. Isso é fundamental para a confiabilidade dos dados.

Viagem no Tempo (Time Travel): Graças ao sistema de snapshots, é possível consultar o estado da tabela em qualquer ponto do tempo. Isso é excelente para auditorias, depuração de pipelines de dados ou para reconstruir o estado de uma tabela.

Alto Desempenho: A estrutura de metadados do Iceberg elimina a necessidade de listar e escanear grandes diretórios de arquivos, uma operação que pode ser muito lenta. Isso resulta em um desempenho de leitura e escrita muito superior.

Compatibilidade: O Iceberg é um padrão aberto com forte suporte de múltiplos mecanismos de processamento e nuvens, evitando o aprisionamento tecnológico (vendor lock-in).

 

Task 1: Criar a estrutura do Object Storage

O Object Storage será usado como um repositório de arquivos padrão. Object Storage é uma maneira simples e de baixo custo de manipular arquivos com performance.

1.1 Criar um compartment

Compartments são importantes para organizar e isolar seus recursos de nuvem. Você pode isolar seus recursos por IAM Policies.

  • Você pode usar este link para entender e configurar as políticas para compartments: Managing Compartments
  • Crie um compartment para hospedar todos os recursos das aplicações neste tutorial. Crie um compartment chamado analytics.
# Criar compartment via CLI
oci iam compartment create \
    --compartment-id <TENANCY_OCID> \
    --name analytics \
    --description "Compartment para aplicações de analytics e data flow"

1.2 Criar buckets no Object Storage

Buckets são contêineres lógicos para armazenar objetos, então todos os arquivos usados para esta demo serão armazenados neste bucket.

# Configurar variáveis
BUCKET_NAME="<your-bucket-name>"
NAMESPACE="<SEU_NAMESPACE>"
COMPARTMENT_ID="<SEU_COMPARTMENT_OCID>"
REGION="<your-region>"

# Criar bucket principal
oci os bucket create \
    --compartment-id $COMPARTMENT_ID \
    --name $BUCKET_NAME \
    --namespace-name $NAMESPACE \
    --region $REGION


### 1.3 Verificar buckets criados


# Listar buckets
oci os bucket list \
    --compartment-id $COMPARTMENT_ID \
    --namespace-name $NAMESPACE \
    --region $REGION

Task 2: Entender o código da aplicação Apache Iceberg

Clone o repositório : https://github.com/sillaslima/iceberg-dataflow-oci

Este tutorial demonstra as funcionalidades do Apache Iceberg em um cenário de processamento de dados de vendas fictício. A aplicação write-iceberg-oci-dataflow.py demosntra as seguintes possibilidades:

  • Geração de dados de vendas
  • Criação de tabela Apache Iceberg com propriedades otimizadas
  • Inserção de dados com garantias ACID
  • Operações de append para adicionar novos dados
  • Consultas SQL analíticas com agregações complexas
  • Demonstração das particularidades do formato Iceberg

2.1 Estrutura do código

Vamos analisar o arquivo write-iceberg-oci-dataflow.py em seções:

Inicialização do Apache Spark com Iceberg

def create_spark_session():
    """Cria uma sessão Spark configurada para OCI Data Flow com Iceberg"""
    print("🔧 Configurando Spark para OCI Data Flow com Apache Iceberg...")
    
    # Configurações fixas do OCI
    region = 'your-region'
    bucket_namespace = 'your-namespace-bucket'
    bucket_name = 'your-bucket'
    warehouse_path = 'oci://your-bucket@your-namespace-bucket/iceberg-warehouse/'
    catalog_name = 'dev'
    
    # Criar sessão Spark com configurações fixas
    spark = SparkSession.builder \
        .appName("WriteIcebergOCIDataFlow") \
        .config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
        .config(f"spark.sql.catalog.{catalog_name}", "org.apache.iceberg.spark.SparkCatalog") \
        .config(f"spark.sql.catalog.{catalog_name}.type", "hadoop") \
        .config(f"spark.sql.catalog.{catalog_name}.warehouse", warehouse_path) \
        .config("spark.sql.warehouse.dir", f"oci://{bucket_name}@{bucket_namespace}/spark-warehouse/") \
        .config("spark.sql.adaptive.enabled", "true") \
        .config("spark.sql.adaptive.coalescePartitions.enabled", "true") \
        .config("spark.sql.execution.arrow.pyspark.enabled", "true") \
        .getOrCreate()
    
    return spark

Explicação das configurações Iceberg:

  • spark.sql.extensions: Habilita as extensões específicas do Iceberg no Spark, permitindo usar comandos SQL como CREATE TABLE ... USING ICEBERG e funcionalidades como Time Travel. Sem esta configuração, o Spark não reconheceria o formato Iceberg.

  • spark.sql.catalog.dev: Define um catálogo personalizado chamado “dev” que será usado para gerenciar tabelas Iceberg. O catálogo é como um “banco de dados” que organiza as tabelas e mantém metadados sobre elas.

  • spark.sql.catalog.dev.type: Especifica que o catálogo “dev” será do tipo “hadoop”, que é compatível com sistemas de arquivos distribuídos como HDFS ou Object Storage (OCI). Outros tipos incluem “jdbc” para bancos relacionais.

  • spark.sql.catalog.dev.warehouse: Define onde o Iceberg armazenará os metadados e dados das tabelas. No OCI, aponta para o Object Storage onde ficam os arquivos Parquet e metadados das tabelas Iceberg.

  • spark.sql.warehouse.dir: Define o diretório padrão do Spark para operações de warehouse. É separado do warehouse Iceberg para evitar conflitos entre diferentes formatos de tabela.

Geração de dados de vendas

def generate_sales_data(spark, num_records=1000):
    """Gera dados de vendas realistas"""
    print(f"\n📊 Gerando {num_records} registros de vendas...")
    
    # Dados de exemplo para vendas
    produtos = ["Notebook Dell", "Smartphone Samsung", "Tablet iPad", ...]
    categorias = ["Eletrônicos", "Informática", "Acessórios", "Móveis", "Iluminação"]
    vendedores = ["João Silva", "Maria Santos", "Pedro Costa", ...]
    clientes = ["Empresa ABC Ltda", "Tech Solutions", "StartupXYZ", ...]
    status = ["Concluída", "Pendente", "Cancelada", "Em Processamento"]
    
    # Schema da tabela de vendas
    schema = StructType([
        StructField("id_venda", StringType(), False),
        StructField("produto", StringType(), True),
        StructField("categoria", StringType(), True),
        StructField("vendedor", StringType(), True),
        StructField("cliente", StringType(), True),
        StructField("quantidade", IntegerType(), True),
        StructField("preco_unitario", DoubleType(), True),
        StructField("desconto_percentual", DoubleType(), True),
        StructField("valor_desconto", DoubleType(), True),
        StructField("valor_total", DoubleType(), True),
        StructField("custo_produto", DoubleType(), True),
        StructField("margem_lucro", DoubleType(), True),
        StructField("status", StringType(), True),
        StructField("data_venda", StringType(), True),
        StructField("timestamp_venda", StringType(), True)
    ])
    
    df = spark.createDataFrame(data, schema)
    return df

Características dos dados:

  • Campos com diferentes tipos de dados (String, Integer, Double, Date, Timestamp)
  • Dados com produtos, categorias, vendedores e clientes
  • Cálculos financeiros incluindo descontos, margem de lucro e valores totais
  • Timestamps distribuídos ao longo de 6 meses para simular dados históricos

Operações Iceberg

def write_sales_to_iceberg(spark, df):
    """Grava dados de vendas na tabela Iceberg"""
    print("\n Gravando dados de vendas no Apache Iceberg...")
    
    catalog_name = "dev"
    table_name = f"{catalog_name}.default.vendas_iceberg"
    
    try:
        # Criar ou substituir tabela Iceberg
        df.writeTo(table_name) \
            .using("iceberg") \
            .tableProperty("write.format.default", "parquet") \
            .tableProperty("write.parquet.compression-codec", "snappy") \
            .tableProperty("write.target-file-size-bytes", "134217728") \
            .createOrReplace()
        
        print("✅ Tabela Iceberg de vendas criada com sucesso!")
        
        # Verificar dados gravados
        vendas_df = spark.read.format("iceberg").load(table_name)
        total_registros = vendas_df.count()
        print(f"✅ Total de registros na tabela: {total_registros}")
        
        return True
    except Exception as e:
        print(f"❌ Erro ao gravar dados no Iceberg: {e}")
        return False

Consultas SQL analíticas

 # Mostrar estatísticas básicas
        print("\n📊 Estatísticas das vendas:")
        vendas_df.createOrReplaceTempView("vendas")
        
        # Resumo por categoria
        resumo_categoria = spark.sql("""
            SELECT 
                categoria,
                COUNT(*) as total_vendas,
                SUM(quantidade) as total_quantidade,
                ROUND(SUM(valor_total), 2) as receita_total,
                ROUND(AVG(valor_total), 2) as ticket_medio,
                ROUND(SUM(margem_lucro), 2) as lucro_total
            FROM vendas 
            GROUP BY categoria
            ORDER BY receita_total DESC
        """)
        resumo_categoria.show()
        
        # Resumo por vendedor
        resumo_vendedor = spark.sql("""
            SELECT 
                vendedor,
                COUNT(*) as total_vendas,
                ROUND(SUM(valor_total), 2) as receita_total,
                ROUND(AVG(valor_total), 2) as ticket_medio
            FROM vendas 
            GROUP BY vendedor
            ORDER BY receita_total DESC
        """)
        resumo_vendedor.show()
        
        # Resumo por status
        resumo_status = spark.sql("""
            SELECT 
                status,
                COUNT(*) as total_vendas,
                ROUND(SUM(valor_total), 2) as receita_total
            FROM vendas 
            GROUP BY status
            ORDER BY total_vendas DESC
        """)
        resumo_status.show()

Particularidades do Apache Iceberg demonstradas:

  1. Formato de arquivo otimizado: Usa Parquet com compressão Snappy para maximizar a compressão dos dados e reduzir o espaço de armazenamento, mantendo alta performance de leitura.
  2. Tamanho de arquivo controlado: Define 128MB por arquivo (134217728 bytes) para otimizar o paralelismo do Spark e evitar arquivos muito pequenos que causam overhead, ou muito grandes que demoram para processar.
  3. Catálogo hierárquico: Usa a estrutura dev.default.vendas_iceberg onde “dev” é o catálogo, “default” é o schema (namespace), e “vendas_iceberg” é a tabela. Isso permite organização e isolamento de diferentes ambientes.
  4. Operações ACID: O método createOrReplace() garante que a operação seja atômica – ou a tabela é criada completamente ou a operação falha, evitando estados inconsistentes.
  5. Leitura otimizada: O spark.read.format("iceberg") ativa otimizações específicas do Iceberg como predicate pushdown, que filtra dados no nível de arquivo antes de carregar na memória.

Operações de Append

def append_sales_data(spark, num_additional_records=100):
    """Adiciona mais dados de vendas à tabela existente"""
    print(f"\n➕ Adicionando {num_additional_records} novos registros de vendas...")
    
    try:
        # Gerar novos dados
        new_df = generate_sales_data(spark, num_additional_records)
        
        # Adicionar à tabela existente
        table_name = "dev.default.vendas_iceberg"
        new_df.writeTo(table_name).append()
        
        print("✅ Novos dados adicionados com sucesso!")
        return True
    except Exception as e:
        print(f"❌ Erro ao adicionar novos dados: {e}")
        return False

Append otimizado: O método .append() adiciona novos dados diretamente à tabela existente sem precisar reescrever os arquivos já existentes. Isso é muito mais eficiente que operações de merge ou upsert em formatos tradicionais.

Task 3: Gerar e subir as dependências

Antes de executar a aplicação no Data Flow, é necessário gerar as dependências do Apache Iceberg usando o Data Flow Dependency Packager. Aqui está o link Dependency Packager

3.1 Executar o script de dependências create-dependencies.sh

Recomendo a leitura detalhada do script para entendimento do processo de geração de dependências.

# Navegar para a pasta scripts
cd apps 

# Executar o script de criação de dependências
chmod +x create-dependencies.sh
./create-dependencies.sh

Overview geral do script:

  • Cria o arquivo packages.txt com as dependências do Iceberg e etc.
  • Baixa a imagem do Data Flow Dependency Packager
  • Executa o empacotador para gerar archive.zip
  • Valida o arquivo gerado

3.2 Verificar dependências geradas

# Verificar se o archive.zip foi criado
ls -la archive.zip

# Verificar conteúdo do archive
unzip -l archive.zip | head -20

# Verificar JARs incluídos
unzip -l archive.zip | grep "\.jar$" | wc -l

3.3 Upload das dependências para OCI

# Upload do archive.zip para o bucket de dependências
oci os object put \
    --bucket-name $BUCKET_NAME" \
    --namespace-name $NAMESPACE \
    --name "dependencies/archive.zip" \
    --file "archive.zip" \
    --region $REGION

# Verificar upload
oci os object list \
    --bucket-name "$BUCKET_NAME" \
    --namespace-name $NAMESPACE \
    --region $REGION

Task 4: Upload da app write-iceberg-oci-dataflow.py

Agora vamos fazer upload do arquivo Python para o Object Storage.

4.1 Executar script de upload

oci os object put \
        --bucket-name $BUCKET_NAME \
        --namespace-name $NAMESPACE \
        --name "scripts/write-iceberg-oci-data-flow.py" \
        --file "write-iceberg-oci-dataflow.py" \
        --region $REGION

### Verificar upload
oci os object list \
    --bucket-name "$BUCKET_NAME" \
    --namespace-name $NAMESPACE \
    --region $REGION

Task 5: Criar aplicação no Data Flow

Agora vamos criar a aplicação Data Flow que executará nosso código Python com Apache Iceberg. Realize a leitura e as alterações necessarias para rodar o script, basicamente as mudanças são sobre:

# Configurações - ALTERE ESTES VALORES
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
APP_NAME="-${TIMESTAMP}"
BUCKET_NAME=""
NAMESPACE=""
COMPARTMENT_ID=""
REGION=""

5.1 Executar script de criação app Data Flow

# Configurações – ALTERE ESTES VALORES BUCKET_NAME=”” NAMESPACE=”” COMPARTMENT_ID=”” REGION=””

# Executar script de criação da aplicação
chmod +x create-dataflow-app.sh
./create-dataflow-app.sh

Overview geral do script:

  • Cria aplicação Data Flow com configurações
  • Define shapes de driver e executor
  • Configura logs bucket
  • Define parâmetros da aplicação

5.2 Verificar aplicação criada

# Listar aplicações no compartment
oci data-flow application list \
    --compartment-id $COMPARTMENT_ID \
    --region $REGION
# Ver detalhes da aplicação criada
APP_ID=$(cat .app-id)
oci data-flow application get \
    --application-id $APP_ID \
    --region $REGION

Task 6: Executar a aplicação

Agora vamos executar nossa aplicação Apache Iceberg no Data Flow.

6.1 Executar script de execução

Realize a leitura e as alterações necessarias para rodar o script, basicamente as mudanças são sobre:

# Configurações - ALTERE ESTES VALORES
NAMESPACE=""
COMPARTMENT_ID=""
REGION=""
# Executar script de execução
chmod +x run-dataflow-app.sh
./run-dataflow-app.sh

Overview do script de execução da aplicação do Data Flow:

  • Inicia execução da aplicação Data Flow
  • Salva Run ID para monitoramento

6.2 Monitorar execução

# Verificar status da execução
RUN_ID=$(cat .run-id)
oci data-flow run get \
    --run-id $RUN_ID \
    --region $REGION \
    --query 'data.lifecycleState'

# Monitorar logs em tempo real
oci data-flow run get \
    --run-id $RUN_ID \
    --region $REGION \
    --query 'data.lifecycleState' \
    --raw-output

6.3 Verificar resultados

# Verificar logs da execução
oci data-flow run get \
    --run-id $RUN_ID \
    --region $REGION \
    --query 'data.{State:lifecycleState,TimeCreated:timeCreated,DisplayName:displayName}'

# Verificar arquivos gerados no bucket
oci os object list \
    --bucket-name $BUCKET_NAME \
    --namespace-name $NAMESPACE \
    --region $REGION \
    --prefix "iceberg-warehouse/""

Task 7: Verificar execução

7.1 Confirmar criação da tabela Iceberg

# Verificar arquivos da tabela Iceberg
oci os object list \
    --bucket-name $BUCKET_NAME \
    --namespace-name $NAMESPACE \
    --region $REGION \
    --prefix "iceberg-warehouse/default/vendas_iceberg/"
# Verificar metadados da tabela
oci os object list \
    --bucket-name $BUCKET_NAME \
    --namespace-name $NAMESPACE \
    --region $REGION \
    --prefix "iceberg-warehouse/default/vendas_iceberg/metadata" --query "data[*].name" --output table

7.2 Confirmar logs de execução

# Verificar logs no bucket de logs
oci os object list \
    --bucket-name "${BUCKET_NAME}-logs" \
    --namespace-name $NAMESPACE \
    --region $REGION

8. Tabelas Iceberg no Autonomous Database

Crie suas credencias, aqui estão as documentações oficiais para consulta:

#Create Credential
begin
    dbms_cloud.create_credential (
        credential_name => 'mycredential',
        username        => '',
        password        => ''
    );
end;


#Visualize Credentials

select credential_name,
       username,
       enabled
from   user_credentials
order by credential_name;

Você pode realizar a leitura dos dados via interface ou via command line, vou demonstrar via command line.

Construindo seu endpoint: A URL base pode ser encontrado quando você realiza o login no conjunto de ferramentas do Database Actions. Por exemplo: https://yourserver.adb.youregion.oraclecloudapps.com/ords/data_studio/_sdw/

A URL base inclui tudo até, menos “_sdw/”. Por exemplo:

https://yourserver.adb.youregion.oraclecloudapps.com/ords/data_studio/

Verificar os cloud-storages-links existentes

curl -s -X GET -H 'accept: application/json' --user 'your-user:your-passwd' https://yourserver.adb.yourregion.oraclecloudapps.com/ords/your-db/_/db-api/latest/data-tools/cloud-storage-links/ | jq

Para criar um Cloud Storage Location

## Create a cloud storage link

curl -s -X POST --user 'your-user:your-passwd' -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
     https://yourserver.adb.yourregion.oraclecloudapps.com/ords/your-db/_/db-api/latest/data-tools/cloud-storage-links/ \
       -d '{
   "cloud_storage_links":[
      {
         "storage_link_name":"name-storage-link",
         "storage_link_description":"description-storage-link",
         "uri":"https://objectstorage.yourregion.oraclecloud.com/n/your-namespace/b/your-bucket/o/"
      }
   ]
}' | jq

Agora vamos chamar a api de Surveys para o data-tools inferir o schema dos dados.

  • object_name : deve ser o metadata que você quer ver os dados no meu caso vou utilizar o metada “v12.metada.json”

  • table_name: o nome da tabela que será criada no AutonomousDB.

curl -s -X POST \
  --user 'your-user:your-passwd' \
  https://yourserver.adb.your-region.oraclecloudapps.com/ords/your-db/_/db-api/latest/data-tools/surveys/ \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "data_loads": [
      {
        "storage_link_name": "name-storage-link",
        "objects": [
          { "object_name": "iceberg-warehouse/default/vendas_iceberg/metadata/v12.metadata.json" }
        ],
        "table_name": "SUM_ICEBERG_2"
      }
    ]
  }' | jq > payload2.json

Esse comando irá gerar um arquivo json com o formato dos dados que serão carregados, abra o arquivo e vejam como a api de “Surveys” inferiu os dados.

Agora vamos chamar o job que irá carregar os dos no tabela “SUM_ICEBERG_2”

## Run the data load job
curl -s -X POST \
    --user 'your-user:your-passwd' \
    https://yourserver.adb.yourregion.oraclecloudapps.com/ords/your-db/_/db-api/latest/data-tools/data-loads/ \
    -H 'accept: application/json' \
    -H 'Content-Type: application/json' \
    -d @payload2.json

repare que no payload2.json ele faz uma referência para o arquivo de metadata que definimos no cloud storage location.

Agora só conectar no seu Autonomous Database e realizar a query na tabela:

select * from SUM_ICEBERG_2;


Conclusão

Neste artigo vimos como unir o poder do OCI Data Flow com o formato de tabelas modernas do Apache Iceberg para processar e organizar dados em larga escala de forma confiável. Também exploramos como integrar esses dados ao Autonomous Database, simplificando o consumo via SQL e potencializando análises avançadas.

Com essa abordagem, é possível construir um data lakehouse moderno na Oracle Cloud, que combina escalabilidade, governança e performance, reduzindo a complexidade operacional e acelerando a jornada de dados da sua organização.

 

Agradecimentos

  • Rodrigo Chafik Choueiri – Cloud Solution Engineer LAD A-Team

Links Relacionados