Ana içeriğe geç
Kesit SQL
Orta · Veri Analisti

Python ile SQL: pandas, parametreli sorgu ve SQLAlchemy

Sorgu sonucunu DataFrame'e almak, güvenli parametre, büyük veride parça parça okuma, tabloya yazma.

Uygulamada aç, 6 alıştırmayı çözÜcretsiz, hesap gerekmez, kurulum yok.

Bu sayfa dersin okuma sürümüdür. Metin bir kutuyu çalıştırmanı ya da adıma geçmeni söylüyorsa dersi uygulamada aç.

Neden Python?

Analist ve veri bilimciler çoğu zaman veriyi SQL ile süzer ve özetler, sonra Python ile görselleştirir, modeller veya otomatikleştirir. İyi pratik: ağır işi veritabanında yap (filtre, birleştirme, toplama), Python'a yalnızca gereken özet satırları getir.

pandas ile okumak

import pandas as pd
from sqlalchemy import create_engine, text

# Bağlantı adresleri
# PostgreSQL : postgresql+psycopg://kullanici:sifre@sunucu:5432/anadolu
# SQL Server : mssql+pyodbc://kullanici:sifre@sunucu/anadolu?driver=ODBC+Driver+18+for+SQL+Server
# MySQL      : mysql+pymysql://kullanici:sifre@sunucu/anadolu
# SQLite     : sqlite:///anadolu.db
engine = create_engine("postgresql+psycopg://analist:***@db.sirket.local/anadolu")

sorgu = text("""
    SELECT date_trunc('month', o.order_date) AS ay,
           o.channel,
           SUM(oi.quantity * oi.unit_price * (1 - oi.discount)) AS ciro
    FROM orders o JOIN order_items oi ON oi.order_id = o.order_id
    WHERE o.status = 'delivered' AND o.order_date >= :baslangic
    GROUP BY 1, 2
""")
df = pd.read_sql(sorgu, engine, params={"baslangic": "2024-01-01"})
pivot = df.pivot(index="ay", columns="channel", values="ciro")
pivot.plot(kind="line")

Parametre: asla metin birleştirme

# YANLIŞ: SQL enjeksiyonuna açık ve tip sorunları çıkarır
sehir = input()
pd.read_sql(f"SELECT * FROM customers WHERE city = '{sehir}'", engine)

# DOĞRU: parametreli
pd.read_sql(text("SELECT * FROM customers WHERE city = :sehir"), engine, params={"sehir": sehir})

# Sürücüye göre yer tutucular: psycopg %s, pyodbc ?, sqlite3 ? veya :ad

Büyük veri

Tabloya yazmak

df_sonuc.to_sql("kampanya_skorlari", engine, schema="analiz", if_exists="replace", index=False, chunksize=10_000)

# İşlem içinde birden çok ifade
with engine.begin() as conn:
    conn.execute(text("DELETE FROM analiz.gunluk WHERE gun = :g"), {"g": gun})
    df_gun.to_sql("gunluk", conn, schema="analiz", if_exists="append", index=False)

SQL'de mi pandas'ta mı?

İşNerede?
Milyonlarca satırı süzmek, birleştirmek, toplamakSQL
Pencere fonksiyonları, kohort, huniSQL (pandas'ta da yapılır ama veri önce taşınmalı)
Görselleştirme, istatistik testleri, makine öğrenmesiPython
Zamanlanmış raporSQL sorgusu + Python betiği + zamanlayıcı (Airflow, cron)
Alıştırmalara geç (6)