Semantic Link ile PBI Model Refresh Etmek

Power BI ve Fabric ortamında veri modelini güncellemek artık eskisi kadar zahmetli bir iş değil; özellikle Sempy ve Fabric Notebooks ile hızlı, esnek ve kod kontrollü otomasyonlar kurabiliyoruz. Bu yazıda, adım adım Sempy ile hem tüm modeli hem de tarihsel (eski) partisyonları nasıl dinamik olarak yenileyebileceğini, tipik senaryolardan kod örneklerine kadar açıklayacağım.

Geleneksel Yöntemler ve Sıkıntılar

Eskiden büyük hacimli modellerde, geriye dönük data değişiklikleri veya sadece belli tabloları/partisyonları güncellemek için PowerShell, Tabular Editor veya SSMS gibi ağır araçlar kullanmak gerekirdi. Artık Fabric’in sunduğu Notebook ve Sempy kütüphanesi sayesinde hem kod ile hem de görsel olarak (pipeline aktiviteleriyle) hedefe yönelik çok kontrollü refresh işlemleri yapabilirsin.

Sempy ve Fabric Notebook ile Otomatik Refresh

1. Ortamı Hazırla

Fabric Notebooks’ta Sempy kütüphanesini kullanmak için önce bir notebook açıyorsun. Eğer özel ortam (custom environment) kullanıyorsan Sempy’yi bir kez yüklemen lazım. Kütüphane 0.7 veya üstü ise yüklemeye gerek olmayabilir.

import sempy.fabric as fabric
import pandas as pd
import datetime
import json

Not: 
Fabric notebook’larda Sempy genellikle önceden yüklü gelir, ancak organizasyonun ortamına göre durum değişebilir. Eğer kendi “Custom environment” ortamınızı kullanıyorsanız pip install sempy-fabric ile kurulumu manuel yapmak gerekebilir. Managed environment kullanıyorsanız Sempy’nin 0.7 ve üstü sürümleri zaten yüklü bulunuyor. Bu nedenle koddan önce import sempy çalışıyor mu kontrol etmek iyi bir pratiktir.

2. Hedef Workspace ve Model Bilgilerini Tanımla

workspace_name = "WORKSPACE_ADI"
dataset_name = "MODEL_ADI"

3. Modelin Yapısını Oku (Tablo ve Partisyonlar)

# Tabloları çek
dftables = fabric.evaluate_dax(
    dataset=dataset_name,
    dax_string="select * from $SYSTEM.TMSCHEMA_TABLES"
)
# Partisyonları çek
dfpartitions = fabric.evaluate_dax(
    dataset=dataset_name,
    dax_string="select * from $SYSTEM.TMSCHEMA_PARTITIONS"
)

Kendi ihtiyacına göre gelen kolonları sadeleştirebilir, tablo ve partisyon adlarını birleştirebilirsin.

4. Dinamik Olarak Yenileyeceğin Partisyonları Belirle

Mesela: Yalnızca bu yılın partisyonlarını yenilemek istiyorsan:

current_year = str(datetime.datetime.now().year)
dfpartitions['PartitionCY'] = dfpartitions['PartitionName'].str[:4] == current_year
yenilenecekler = dfpartitions[dfpartitions['PartitionCY']]

Sonra bunu Sempy’nin refresh fonksiyonu için bir listeye çevir:

objects_to_refresh = [
    {'table': row['TableName'], 'partition': row['PartitionName']}
    for _, row in yenilenecekler.iterrows()
]

Dikkat
Yukarıdaki örnekte partisyon adının ilk 4 karakterinin yıl olduğu varsayılmıştır: Eğer modelinizde partisyon adları farklı bir formatta ise (örn. 2025_Q1, 2025-01, Fact_2025_01, vb.) kendi adlandırma standardınıza göre filtreleme koşulunu uyarlamanız gerekir. Aksi durumda istenmeyen partisyonlar da refreshe dahil olabilir.

5. Refresh Komutunu Çalıştır

request_id = fabric.refresh_dataset(
    workspace=workspace_name,
    dataset=dataset_name,
    objects=objects_to_refresh,
    refresh_type="full",
    apply_refresh_policy=False
)

Burada apply_refresh_policy=False ile incremental refresh politikasını pas geçiyorsun, tüm istediğin partisyonları yeniliyorsun.

Önemli Uyarı: 
Örnekte refresh_type=”full” ve apply_refresh_policy=False kullanıyorum. Bu kombinasyon incremental refresh politikasını devre dışı bırakarak seçilen tüm partisyonları tam yenileme (full refresh) yapar.
Büyük hacimli modellerde bu işlem maliyetli olabilir, bu yüzden hedeflenen partisyon seçimlerinin doğru olduğundan emin olun. Eğer sadece incremental politika kapsamındaki son dönemleri yenilemek istiyorsanız apply_refresh_policy=True seçeneği değerlendirilebilir.

6. Sonuçları ve Logları Takip Et

İşlemin başarıyla tamamlanıp tamamlanmadığını request id ile takip edebilirsin. Ayrıca refresh taleplerini ve ayrıntılı sonucu çekmek için Sempy’de şu fonksiyonlar var:

refreshes = fabric.list_refresh_requests(dataset=dataset_name, workspace=workspace_name)
details = fabric.get_refresh_execution_details(
    dataset=dataset_name, workspace=workspace_name,
    refresh_request_id=refreshes.iloc[^0]["Request Id"]
)

Bu komutlar sana işlemin hangi aşamada olduğunu, varsa hata ya da uyarıları gösterir.

Hata İzleme:
list_refresh_requests() ve get_refresh_execution_details() üzerinden refresh durumlarını takip edebilirsiniz.

Refresh işlemi şu durumlarda başarısız olabilir:
• Tablo ya da partisyon kilitlenmişse
• kaynak yetersizliği
• timeout
• upstream veri hataları

Hata mesajını yakalamak için:

details = fabric.get_refresh_execution_details(…)
print(details[“Status”])
print(details.get(“ErrorMessage”))

Bu logları pipeline otomasyonlarında “retry” stratejilerine bağlamak, büyük modellerde pratik bir çözümdür.

Hızlı Notlar ve Gerçek Senaryo

  • Incremental refresh politikasına rağmen geriye dönük değişiklik olduğunda (örneğin, geçmiş aylara veri eklendiğinde), sadece o yılın partisyonlarını yenileyerek güncel veri gösterebilirsin.
  • Bu yöntemler sayesinde modeldeki eski partisyonlar, manuel işlem yapmadan Python kodu ve Fabric Notebooks ile düzenli olarak güncellenebilir.
  • Refresh işlemini otomatikleştirmek için Notebook’u bir pipeline’a ekleyip zamanlayabilirsin.
  • Parallelism, retry count gibi parametrelerle refresh işlemini optimize edebilirsin; özellikle büyük hacimli tablolarda refresh süresini ciddi şekilde azaltır.

Diğer Bazı Noktalar:

  • Eski partisyonlara veri eklendi ve incremental refresh aktifse? Sadece incremental window yenilenir, eskiye dokunmaz. Bu kodlarla eski partisyonlara dokunabilirsin.
  • Kodun optimizasyonu? Elbette, Python bilen biri daha verimli hale getirebilir; ama temel akışı doğru kurarsan işini görür.
  • Dataset üzerinde Sempy ile refresh yapabilmek için şu erişim haklarına sahip olmanız gerekir:

    • Workspace’te Contributor veya üzeri yetki

    • Dataset üzerinde Read/Write izni

    • Service Principal kullanıyorsanız Fabric’te “Admin” tarafından gerekli rol atamalarının yapılmış olması


API tabanlı bu işlemler güvenlik gereksinimlerine takılabileceği için otomasyonlarda kullanılan kimliğin Workspace bazlı izinlerinin doğru verildiğinden emin olun.

Kaynaklar: