ContainerTransformer
Visão geral
Converte nós Container do Tableau em instruções SQL SELECT com múltiplas transformações. Nós Container agrupam múltiplas operações (adicionar colunas, remover colunas, filtros etc.) em uma única unidade lógica.
Tipo de nó: .v1.Container
Saída: SQL SELECT com colunas derivadas e filtros
Recursos
- Adição de colunas calculadas (AddColumn)
- Remoção de colunas (RemoveColumns)
- Renomeação de colunas (RenameColumn)
- Filtragem de linhas (FilterOperation, ValueFilter)
- Mesclagem de colunas (MergeColumns)
- Conversão de tipos (ChangeColumnType)
- Processamento sequencial de operações
Exemplo de nó Tableau
Exemplo 1: adicionar componentes de data e remover a coluna original
Entrada (formato Tableau)
{
"id": "e3f5b8c4-9093-4214-9ba5-4da0697a365c",
"name": "Clean Date Fields",
"node_type": ".v1.Container",
"base_type": "container",
"loomContainer": {
"nodes": {
"0d180902-5195-4437-8f6e-98c0a111284f": {
"id": "0d180902-5195-4437-8f6e-98c0a111284f",
"name": "Add Year",
"nodeType": ".v1.AddColumn",
"columnName": "Year",
"expression": "YEAR([Invoice Date])"
},
"76a04765-f5fa-415a-a1cb-9f2ad241bbc5": {
"id": "76a04765-f5fa-415a-a1cb-9f2ad241bbc5",
"name": "Add Month",
"nodeType": ".v1.AddColumn",
"columnName": "Month",
"expression": "MONTH([Invoice Date])"
},
"854e5241-a7d4-4569-8651-d5bebe9e2aa3": {
"id": "854e5241-a7d4-4569-8651-d5bebe9e2aa3",
"name": "Remove Invoice Date",
"nodeType": ".v1.RemoveColumns",
"columnNames": ["Invoice Date"]
}
},
"initialNodes": ["0d180902-5195-4437-8f6e-98c0a111284f"]
}
}
Esquema de entrada
[
{"name": "division", "type": "string"},
{"name": "sales_amount", "type": "real"},
{"name": "order_type", "type": "string"},
{"name": "document_number", "type": "string"},
{"name": "invoice_date", "type": "date"}
]
SQL gerado
SELECT
division,
sales_amount,
order_type,
document_number,
YEAR(CAST(invoice_date AS DATE)) AS year,
MONTH(CAST(invoice_date AS DATE)) AS month
FROM previous_stage_V0S12
Esquema de saída
{
"division": "string",
"sales_amount": "real",
"order_type": "string",
"document_number": "string",
"year": "integer",
"month": "integer"
}
Exemplo 2: adicionar coluna calculada
Entrada (formato Tableau)
{
"id": "f4e5d6c7-b8a9-0c1d-2e3f-4a5b6c7d8e9f",
"name": "Calculate Profit",
"node_type": ".v1.Container",
"base_type": "container",
"loomContainer": {
"nodes": {
"a1b2c3d4-e5f6-7890-abcd-ef1234567890": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Add Profit",
"nodeType": ".v1.AddColumn",
"columnName": "Profit",
"expression": "[Sales Amount] - [Cost Amount]"
}
},
"initialNodes": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890"]
}
}
SQL gerado
SELECT
product_code,
sales_amount,
cost_amount,
(sales_amount - cost_amount) AS profit
FROM products_V0S5
Exemplo 3: filtrar linhas
Entrada (formato Tableau)
{
"id": "9a8b7c6d-5e4f-3a2b-1c0d-9e8f7a6b5c4d",
"name": "Filter Active Orders",
"node_type": ".v1.Container",
"base_type": "container",
"loomContainer": {
"nodes": {
"b2c3d4e5-f6a7-8901-bcde-f12345678901": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"name": "Filter Status",
"nodeType": ".v1.FilterOperation",
"expression": "[Status] = 'Active'"
}
},
"initialNodes": ["b2c3d4e5-f6a7-8901-bcde-f12345678901"]
}
}
SQL gerado
SELECT
order_id,
customer_id,
status,
order_date
FROM orders_V0S8
WHERE status = 'Active'
Exemplo 4: múltiplas operações (adicionar, renomear, remover)
Entrada (formato Tableau)
{
"id": "8c7d6e5f-4a3b-2c1d-0e9f-8a7b6c5d4e3f",
"name": "Transform Customer Data",
"node_type": ".v1.Container",
"base_type": "container",
"loomContainer": {
"nodes": {
"node1": {
"nodeType": ".v1.AddColumn",
"columnName": "Full Name",
"expression": "[First Name] + ' ' + [Last Name]"
},
"node2": {
"nodeType": ".v1.RemoveColumns",
"columnNames": ["First Name", "Last Name"]
},
"node3": {
"nodeType": ".v1.RenameColumn",
"columnName": "Customer ID",
"newColumnName": "ID"
}
},
"initialNodes": ["node1"]
}
}
SQL gerado
SELECT
customer_id AS id,
email,
phone,
(first_name || ' ' || last_name) AS full_name
FROM customers_V0S3
Como funciona
1. Identificar a estrutura do Container
Lê o objeto loomContainer com os nós internos:
{
"loomContainer": {
"nodes": { ... },
"initialNodes": ["first-node-id"]
}
}
2. Processar os nós internos sequencialmente
Executa as operações na ordem definida pelas relações nextNodes:
- Começa com initialNodes
- Aplica cada operação
- Segue a sequência nextNodes
- Constrói a transformação cumulativa
3. Operações suportadas
AddColumn
Adiciona colunas calculadas usando expressões:
"expression": "YEAR([Invoice Date])"
Converte em:
YEAR(CAST(invoice_date AS DATE)) AS year
RemoveColumns
Exclui colunas da saída:
"columnNames": ["Invoice Date", "Temp Field"]
RenameColumn
Renomeia colunas no SELECT:
"columnName": "Old Name"
"newColumnName": "New Name"
Converte em:
old_name AS new_name
FilterOperation / ValueFilter
Adiciona condições à cláusula WHERE:
"expression": "[Status] = 'Active'"
Converte em:
WHERE status = 'Active'
MergeColumns
Concatena colunas:
"expression": "[First] + ' ' + [Last]"
Converte em:
(first || ' ' || last) AS merged_column
ChangeColumnType
Converte os tipos das colunas:
"fields": {
"Amount": {"type": "integer"}
}
Converte em:
CAST(amount AS INTEGER) AS amount
4. Gerar SQL
Cria uma única instrução SELECT combinando todas as operações:
SELECT
<existing_columns>,
<added_columns>,
<renamed_columns AS aliases>
FROM input_table
WHERE <filter_conditions>
Suporte a expressões
Nós Container usam expressões Tableau Prep que são convertidas em SQL:
Funções de data
| Expressão Tableau | SQL de saída |
|---|---|
YEAR([Date]) | YEAR(CAST(date AS DATE)) |
MONTH([Date]) | MONTH(CAST(date AS DATE)) |
DAY([Date]) | DAY(CAST(date AS DATE)) |
DATEPART('quarter', [Date]) | QUARTER(CAST(date AS DATE)) |
Funções de texto
| Expressão Tableau | SQL de saída |
|---|---|
[First] + ' ' + [Last] | (first || ' ' || last) |
UPPER([Name]) | UPPER(name) |
LOWER([Name]) | LOWER(name) |
TRIM([Name]) | TRIM(name) |
Funções matemáticas
| Expressão Tableau | SQL de saída |
|---|---|
[Sales] - [Cost] | (sales - cost) |
[Sales] * 1.1 | (sales * 1.1) |
ROUND([Amount], 2) | ROUND(amount, 2) |
Lógica condicional
| Expressão Tableau | SQL de saída |
|---|---|
IF [Status] = 'A' THEN 'Active' ELSE 'Inactive' END | CASE WHEN status = 'A' THEN 'Active' ELSE 'Inactive' END |
Ordem de execução das operações
Nós Container processam as operações sequencialmente:
1. AddColumn "Year" → Adds year column
2. AddColumn "Month" → Adds month column (can reference year)
3. RemoveColumns → Removes invoice_date
4. RenameColumn → Renames columns
5. FilterOperation → Applies WHERE clause
Operações posteriores podem referenciar colunas criadas por operações anteriores.
Transformador híbrido
ContainerTransformer é um transformador híbrido que:
- Usa conversão determinística para operações simples (RenameColumn, RemoveColumns)
- Usa auxílio de LLM para expressões complexas (AddColumn com cálculos)
- Combina as duas abordagens para obter os melhores resultados
Limitações
- ⚠️ Expressões complexas podem exigir LLM - Expressões Tableau muito complexas podem precisar de auxílio de IA para uma conversão precisa
- ⚠️ Diferenças na sintaxe de expressões - Algumas funções Tableau podem não ter equivalentes SQL diretos
- ⚠️ Consideração de desempenho - Múltiplas operações em um contêiner são combinadas em um único SELECT para maior eficiência
Boas práticas
Quando usar o transformador Container
- ✅ Múltiplas transformações relacionadas no mesmo conjunto de dados
- ✅ Colunas calculadas a partir de campos existentes
- ✅ Operações de limpeza de dados (remover, renomear, filtrar)
- ✅ Extração de componentes de data de campos de timestamp
Simplificação de contêineres
Se um contêiner tiver muitas operações:
- Revise redundâncias - Remova operações desnecessárias
- Agrupe logicamente - Mantenha operações relacionadas juntas
- Teste incrementalmente - Verifique a saída de cada operação
Transformadores relacionados
- AggregateTransformer - Para agrupamento e agregações após as transformações
- JoinTransformer - Para combinar conjuntos de dados transformados
- OutputTransformer - Para a saída final após as transformações