Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124

Apache Superset, veritabanlarına bağlanarak SQL ile veri analizi yapmayı ve bu verileri grafik ve dashboard’lar halinde görselleştirmeyi sağlayan açık kaynaklı bir BI aracıdır. Bu yazıda, Superset’in Docker ile kurulumu, veritabanı bağlantısı, dataset oluşturma ve dashboard hazırlama süreci pratik örneklerle anlatılmaktadır.
Apache Superset, açık kaynak bir BI (Business Intelligence) ve data keşif aracıdır.
Neden önemli?
Superset’te en çok duyacağın kavramlar:
Superset’in bağlandığı kaynak. Örn: PostgreSQL.
Bağlantı formatı (SQLAlchemy URI):
postgresql+psycopg2://kullanici:sifre@host:5432/veritabani
Chart’ların beslendiği yapı. Bir tablo (orders) veya view (orders_daily) olabilir.
Dataset + metrik/dimension + filtre + görsel türü.
Birden fazla chart’ı bir ekranda toplar, filtreler/sekme düzeni kurarsın.
Kim hangi veriyi/alanı görebilir? Prod ortamda kritik.
Database → Superset → Dashboard → User
Önemli nokta: Superset genelde veriyi kendi içinde “saklamaz”. Asıl kaynak DB’dir. (Cache/metadata ayrı)
Aşağıdaki kurulum senaryosu:
Not: En pratik yöntem, Superset’in resmi docker-compose örneğini baz almak ve repo olarak düzenlemek.
superset-proof/
docker/
docker-compose.yml
superset.env
db/
init/
01_schema.sql
02_seed.sql
README.md
docker/docker-compose.yml
version: "3.8"
services:
db:
image: postgres:16
container_name: demo_postgres
environment:
POSTGRES_USER: demo
POSTGRES_PASSWORD: demo
POSTGRES_DB: demo
ports:
- "5432:5432"
volumes:
- ../db/init:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U demo -d demo"]
interval: 5s
timeout: 5s
retries: 20
superset:
image: apache/superset:latest
container_name: superset
depends_on:
db:
condition: service_healthy
env_file:
- ./superset.env
ports:
- "8088:8088"
command: >
bash -c "
superset db upgrade &&
superset fab create-admin
--username admin
--firstname Admin
--lastname User
--email admin@local
--password admin
|| true &&
superset init &&
superset run -h 0.0.0.0 -p 8088
"
db: Demo verisini koyacağımız PostgreSQLvolumes: db/init içindeki SQL dosyaları container ilk kalkışta otomatik çalışırsuperset: Superset container’ısuperset db upgrade: metadata tablolarını hazırlarcreate-admin: admin hesabı oluşturur (ikinci çalıştırmada “zaten var” olabilir, || true ile tolere)superset init: örnek ayarlar, roller, izinlerrun: 8088’den ayağa kaldırırdocker/superset.env
SUPERSET_SECRET_KEY=change_me_to_a_long_random_string
TZ=Europe/Istanbul
Prod’da SECRET_KEY mutlaka güçlü olmalı.
Proje kökünde:
cd docker
docker compose up -d
docker compose logs -f superset
Tarayıcı:
http://localhost:8088adminadmindb/init/01_schema.sql
CREATE TABLE IF NOT EXISTS orders (
id BIGSERIAL PRIMARY KEY,
order_date TIMESTAMP NOT NULL,
customer_id BIGINT NOT NULL,
country TEXT NOT NULL,
category TEXT NOT NULL,
revenue NUMERIC(12,2) NOT NULL,
quantity INT NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_orders_order_date ON orders(order_date);
CREATE INDEX IF NOT EXISTS ix_orders_country ON orders(country);
CREATE INDEX IF NOT EXISTS ix_orders_category ON orders(category);
db/init/02_seed.sql
INSERT INTO orders (order_date, customer_id, country, category, revenue, quantity)
SELECT
NOW() - (random() * interval '180 days') AS order_date,
(random() * 5000)::int + 1 AS customer_id,
(ARRAY['TR','DE','NL','UK','US'])[floor(random()*5)+1] AS country,
(ARRAY['Electronics','Fashion','Home','Grocery'])[floor(random()*4)+1] AS category,
round((random() * 500 + 10)::numeric, 2) AS revenue,
(random()*5)::int + 1 AS quantity
FROM generate_series(1, 20000);
Bu seed:
Superset → Settings → Database Connections → + Database
SQLAlchemy URI:
postgresql+psycopg2://demo:demo@db:5432/demo
Dikkat: Docker ağında superset container’ından DB’ye giderken host
localhostdeğil, service adı olandbkullanılmalı.
“Test Connection” → başarılı olmalı.
Superset → Datasets → + Dataset
Kaydet.
Superset → SQL Lab → SQL Editor
SELECT
date_trunc('day', order_date) AS day,
SUM(revenue) AS total_revenue
FROM orders
GROUP BY 1
ORDER BY 1;
SELECT
country,
SUM(revenue) AS total_revenue
FROM orders
GROUP BY country
ORDER BY total_revenue DESC;
SELECT
category,
SUM(revenue) AS total_revenue
FROM orders
GROUP BY category
ORDER BY total_revenue DESC;
SELECT
AVG(revenue) AS avg_order_value
FROM orders;
Aşağıdaki 4 chart ile “demo dashboard” çok net olur.
order_dateSUM(revenue)Bu chart neyi gösterir?
countrySUM(revenue)categorySUM(revenue)COUNT(*) (sipariş sayısı)AVG(revenue) (AOV)Superset’te metrik tanımları genelde dataset içinde “metrics” olarak kaydedilebilir. Böylece tekrar kullanırsın.
Dashboard oluştur:
Native Filters ekle:
Bu filtreleri tüm grafiklere bağla.
Dashboard’ın temiz çalışması için DB’de view üretmek gerçek hayatta sık görülür.
Örn: Günlük özet view:
CREATE OR REPLACE VIEW orders_daily AS
SELECT
date_trunc('day', order_date) AS day,
country,
category,
COUNT(*) AS order_count,
SUM(revenue) AS revenue,
AVG(revenue) AS aov
FROM orders
GROUP BY 1,2,3;
Bunu dataset yaparsın:
day time columnSuperset’te metric ifadesi olarak:
SUM(revenue)COUNT(*)AVG(revenue)SUM(revenue) / NULLIF(SUM(quantity), 0)Sebep: Docker içinde localhost kullanmak
Çözüm: URI’da host db olmalı:
postgresql+psycopg2://demo:demo@db:5432/demo
Sebep: Superset image’ında ilgili DB driver yok
Çözüm: Resmi image genelde PostgreSQL’i destekler ama sorun olursa custom image gerekebilir:
apache/superset üzerine pip install psycopg2-binaryÇözüm: Container command içinde:
superset db upgradesuperset initSebep: Time column seçilmedi veya timezone/time grain uyumsuz
Çözüm: Dataset’te doğru time column = order_date seç, chart’ta “Time range” ver.
Sebep: Index yok, sorgu ağır, çok geniş tarih aralığı
Çözüm: Index ekle (order_date, country, category), time range sınırla, view/materialized view düşün.
date_trunc() ile “grain” sabitle.order_date index’i.CH__Revenue_Trend_DailyCH__Revenue_By_CountryDS__orders_dailyDB__demo_postgres