google-sheetsno-codedata-laketutorial

De Google Sheets para um Data Lake Consultável em 3 Comandos

Michael San Martim · 2026-04-26

Toda empresa tem aquela planilha. O rastreador de orçamento de marketing. A previsão de vendas. O roadmap de produto com 47 abas. Ela vive no Google Sheets porque é onde times não-técnicos trabalham.

Você precisa desses dados no seu data lake. Não como um export CSV que você lembra de baixar nas sextas. Como uma tabela Parquet adequada que você pode fazer JOIN com seus dados de produção e consultar com SQL.

O DataSpoc Pipe tem um tap Google Sheets integrado. Sem pacotes extras, sem dança OAuth para sheets públicas, sem arquivos de configuração Singer. Três comandos.

O Cenário

Seu time de marketing mantém um Google Sheet com dados de gasto em campanhas:

https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms/edit

Ele tem duas planilhas (abas):

  • campaigns — nome da campanha, canal, orçamento, gasto, data_início, data_fim
  • daily_metrics — data, campanha, impressões, cliques, conversões, custo

Você quer isso no seu data lake como Parquet, consultável com SQL, com JOIN possível com seus dados de receita do Postgres.

Comando 1: Inicializar o Projeto

Terminal window
dataspoc-pipe init marketing-lake --bucket s3://company-marketing

Saída:

Created project: marketing-lake/
dataspoc-pipe.yaml
pipelines/

Comando 2: Adicionar o Pipeline Google Sheets

Terminal window
dataspoc-pipe add sheets-marketing \
--source google_sheets \
--url "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms" \
--target s3://company-marketing

Isso gera a configuração do pipeline:

pipelines/sheets-marketing.yaml
pipeline: sheets-marketing
source:
type: google_sheets
url: "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms"
sheets:
- campaigns
- daily_metrics
target:
type: s3
bucket: s3://company-marketing
prefix: raw/google_sheets

Pronto. Sem chaves de API necessárias para sheets públicas. Para sheets privadas, defina GOOGLE_SERVICE_ACCOUNT_JSON como variável de ambiente.

Comando 3: Executar

Terminal window
dataspoc-pipe run sheets-marketing

Saída:

[sheets-marketing] Starting extraction...
[sheets-marketing] Extracting sheet: campaigns (156 rows)
[sheets-marketing] Extracting sheet: daily_metrics (4,380 rows)
[sheets-marketing] Writing: s3://company-marketing/raw/google_sheets/campaigns/20260415_070000.parquet
[sheets-marketing] Writing: s3://company-marketing/raw/google_sheets/daily_metrics/20260415_070000.parquet
[sheets-marketing] Done. 2 tables, 4,536 rows, 3.2s

Seu data lake agora tem:

s3://company-marketing/
.dataspoc/
manifest.json
state/sheets-marketing/state.json
raw/google_sheets/
campaigns/
20260415_070000.parquet
daily_metrics/
20260415_070000.parquet

Consultando com DataSpoc Lens

Agora conecte o Lens e comece a consultar:

Terminal window
dataspoc-lens add-bucket marketing s3://company-marketing
dataspoc-lens shell

Você agora está em um shell SQL DuckDB com seus dados do Sheets montados:

-- See available tables
SHOW TABLES;
┌─────────────────────────────────────┐
│ name │
├─────────────────────────────────────┤
│ raw__google_sheets__campaigns │
│ raw__google_sheets__daily_metrics │
└─────────────────────────────────────┘
-- Total spend by channel
SELECT
channel,
COUNT(*) as campaigns,
SUM(spend) as total_spend,
SUM(budget) as total_budget,
ROUND(SUM(spend) / SUM(budget) * 100, 1) as pct_used
FROM raw__google_sheets__campaigns
GROUP BY channel
ORDER BY total_spend DESC;
┌──────────┬───────────┬─────────────┬──────────────┬──────────┐
│ channel │ campaigns │ total_spend │ total_budget │ pct_used │
├──────────┼───────────┼─────────────┼──────────────┼──────────┤
│ google │ 45 │ 125,400 │ 150,000 │ 83.6 │
│ meta │ 38 │ 98,200 │ 120,000 │ 81.8 │
│ linkedin │ 22 │ 67,800 │ 80,000 │ 84.8 │
│ twitter │ 51 │ 34,500 │ 50,000 │ 69.0 │
└──────────┴───────────┴─────────────┴──────────────┴──────────┘
-- Cost per conversion by campaign (last 30 days)
SELECT
c.campaign_name,
c.channel,
SUM(d.cost) as total_cost,
SUM(d.conversions) as total_conversions,
ROUND(SUM(d.cost) / NULLIF(SUM(d.conversions), 0), 2) as cpa
FROM raw__google_sheets__daily_metrics d
JOIN raw__google_sheets__campaigns c ON d.campaign = c.campaign_name
WHERE d.date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY c.campaign_name, c.channel
HAVING SUM(d.conversions) > 0
ORDER BY cpa ASC
LIMIT 10;
┌──────────────────────┬──────────┬────────────┬──────────────────┬───────┐
│ campaign_name │ channel │ total_cost │ total_conversions│ cpa │
├──────────────────────┼──────────┼────────────┼──────────────────┼───────┤
│ spring_retargeting │ meta │ 2,340 │ 156 │ 15.00 │
│ brand_search │ google │ 4,200 │ 245 │ 17.14 │
│ lookalike_q2 │ meta │ 3,800 │ 198 │ 19.19 │
│ dev_tools_launch │ linkedin │ 5,600 │ 112 │ 50.00 │
└──────────────────────┴──────────┴────────────┴──────────────────┴───────┘

AI Ask: Queries em Linguagem Natural

Para exploração rápida, use AI Ask:

Terminal window
dataspoc-lens ask "Which campaign had the best conversion rate last week?"

Saída:

SQL:
SELECT
c.campaign_name,
c.channel,
SUM(d.clicks) as clicks,
SUM(d.conversions) as conversions,
ROUND(SUM(d.conversions)::FLOAT / NULLIF(SUM(d.clicks), 0) * 100, 2) as conversion_rate
FROM raw__google_sheets__daily_metrics d
JOIN raw__google_sheets__campaigns c ON d.campaign = c.campaign_name
WHERE d.date >= CURRENT_DATE - INTERVAL '7 days'
GROUP BY c.campaign_name, c.channel
ORDER BY conversion_rate DESC
LIMIT 1
Result:
campaign_name: spring_retargeting
channel: meta
conversion_rate: 12.4%
Terminal window
dataspoc-lens ask "Compare Google vs Meta spend efficiency this month"
SQL:
SELECT
c.channel,
SUM(d.cost) as spend,
SUM(d.conversions) as conversions,
ROUND(SUM(d.cost) / NULLIF(SUM(d.conversions), 0), 2) as cost_per_conversion
FROM raw__google_sheets__daily_metrics d
JOIN raw__google_sheets__campaigns c ON d.campaign = c.campaign_name
WHERE d.date >= DATE_TRUNC('month', CURRENT_DATE)
AND c.channel IN ('google', 'meta')
GROUP BY c.channel
Result:
┌─────────┬────────┬─────────────┬─────────────────────┐
│ channel │ spend │ conversions │ cost_per_conversion │
├─────────┼────────┼─────────────┼─────────────────────┤
│ meta │ 12,400 │ 523 │ 23.71 │
│ google │ 18,900 │ 687 │ 27.51 │
└─────────┴────────┴─────────────┴─────────────────────┘

Mantendo Atualizado

Configure um cron para atualizar diariamente:

Terminal window
# Refresh sheets data every morning at 6am
0 6 * * * cd /opt/marketing-lake && dataspoc-pipe run sheets-marketing

Ou use o agendamento integrado do Pipe:

pipelines/sheets-marketing.yaml
pipeline: sheets-marketing
schedule: "0 6 * * *"
source:
type: google_sheets
url: "https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms"
sheets:
- campaigns
- daily_metrics
target:
type: s3
bucket: s3://company-marketing
prefix: raw/google_sheets

Sheets Privadas

Para sheets que não são compartilhadas publicamente, use uma Google Service Account:

Terminal window
export GOOGLE_SERVICE_ACCOUNT_JSON=/path/to/service-account.json
dataspoc-pipe run sheets-marketing

Compartilhe a sheet com o email da service account, e funciona exatamente da mesma forma.

Fazendo JOIN de Dados do Sheets com Outras Fontes

O verdadeiro poder é combinar dados de planilha com seus dados de produção. Se você também tem um pipeline Postgres:

-- Join marketing spend with actual revenue
SELECT
c.channel,
SUM(d.cost) as marketing_spend,
SUM(o.amount) as revenue,
ROUND(SUM(o.amount) / NULLIF(SUM(d.cost), 0), 2) as roas
FROM raw__google_sheets__daily_metrics d
JOIN raw__google_sheets__campaigns c ON d.campaign = c.campaign_name
JOIN raw__postgres__orders o ON o.utm_source = c.channel
AND o.created_at::DATE = d.date
WHERE d.date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY c.channel
ORDER BY roas DESC;

Por Que Isso Funciona para Times Pequenos

  • Sem infraestrutura — sem Airflow, sem Fivetran, sem dbt Cloud
  • Sem codificação — o time de negócio continua editando sua planilha, você ganha Parquet
  • SQL em tudo — uma vez que é Parquet, é apenas mais uma tabela
  • Pronto para IA — AI Ask funciona com dados de planilha igual aos dados de produção
  • Grátis — DataSpoc Pipe é open source, Google Sheets API é grátis para uso razoável

Três comandos. Planilha pública para data lake consultável. Essa é a promessa das ferramentas de dados modernas.

Recomendados