Ümit Kara | Dynamics 365, Power Platform ve SharePoint Üzerine Notlar paylaşımnoktası
Dynamics365 · 28 Ağustos 2026 · 4 dk okuma

Xrm.WebApi’den Python SDK’ya: Aynı Sorguyu İki Dilde Yazmak

Geçen hafta form script’lerinde Xrm.WebApi.retrieveMultipleRecords ile nasıl sorgu yazdığımı anlatmıştım. Bu hafta aynı mantığı, form dışında — bir otomasyon/analiz script’inde — Python’da nasıl yazdığımı denedim.

Çünkü: Wave 1 ile gelen resmi Dataverse SDK for Python (şu anda preview modunda) çıktı ve merak ettim — JavaScript tarafında öğrendiğim OData mantığı Python’a nasıl taşınıyor.

Problem

Elimde şöyle bir ihtiyaç vardı: belirli bir account’a bağlı aktif contact’ları, bağlı oldukları account’un adı ve numarasıyla birlikte çekip bir CSV’ye dökmem gerekiyordu — form içinde değil, ayrı bir Python script’inde. Form tarafında bunu uzun zamandır şöyle yazıyorum:

Xrm.WebApi.retrieveMultipleRecords(
  "contact",
  "?$select=fullname&$filter=_parentcustomerid_value eq " + accountId +
  " and statecode eq 0" +
  "&$expand=parentcustomerid_account($select=name,accountnumber)"
).then(function (result) {
  result.entities.forEach(function (contact) {
    console.log(contact.fullname);
  });
});

Bu kalıbı ezbere biliyorum ama iki şey her seferinde canımı sıkıyor: _value son ekini unutmak (lookup filtrelerken en sık yaptığım hata) ve string concatenation’ın okunabilirliği bozması. Python tarafında da string ile aynı OData sorgusunu elle kurmak zorunda mıyım, yoksa daha iyi bir yol var mı — asıl merak ettiğim buydu.

Kök Neden / Bağlam

Dataverse SDK for Python, aslında yeni değil — aynı Dataverse Web API’sinin (yani senin Xrm.WebApi‘nin arkasındaki aynı OData katmanının) üzerine kurulu bir Python istemcisi. Yani JS tarafında öğrendiğin $select, $filter, $expand mantığı boşa gitmiyor; SDK bunu senin yerine, güvenli bir fluent QueryBuilder ile üretiyor. Fark, sorguyu string olarak elle yazmak yerine method chaining ile kurman — ki bu tam olarak _value gibi syntax hatalarını yapısal olarak imkânsız hale getiriyor.

Çözüm

Kurulum:

pip install PowerPlatform-Dataverse-Client azure-identity

Bağlantı (development ortamında interactive login ile):

from azure.identity import InteractiveBrowserCredential
from PowerPlatform.Dataverse.client import DataverseClient

credential = InteractiveBrowserCredential()
client = DataverseClient("https://<myorg>.crm.dynamics.com", credential)

Ve yukarıdaki JS sorgusunun Python karşılığı:

from PowerPlatform.Dataverse.models.filters import col

result = (
    client.query.builder("contact")
    .select("fullname")
    .where(col("_parentcustomerid_value") == account_id)
    .where(col("statecode") == 0)
    .execute()
)

for contact in result:
    print(contact["fullname"])

Dikkat edilmesi gereken nokta: _value son eki burada da var — SDK bu OData kısıtını ortadan kaldırmıyor, çünkü alttaki API aynı. Ama col(...) üzerinden yazınca IDE’nin otomatik tamamlaması ve tip kontrolü devreye giriyor; string’i elle birleştirirken yapılan sessiz hatalar (sorgu hata vermez, sonuç boş döner — tam da JS yazımda bahsettiğim tuzak) burada çok daha az olası.

Bonus: SDK, sonucu doğrudan pandas DataFrame olarak da döndürebiliyor — data scientist’ler için CSV’ye dökme adımını tek satıra indiriyor.

Ders / Checklist

  • Xrm.WebApi bildiğin her şey boşa gitmiyor. Aynı OData kavramları ($select, $filter, $expand, lookup’larda _value son eki) Python SDK’da da geçerli — SDK bunu senin yerine üretiyor, ortadan kaldırmıyor.
  • Fluent QueryBuilder, syntax hatalarını azaltıyor ama sıfırlamıyor. _value son ekini hâlâ bilmen gerekiyor; sadece string concatenation kaynaklı can sıkıcı hatalardan kurtuluyorsun.
  • Preview aşamasında. (pip install PowerPlatform-Dataverse-Client==<sürüm>), breaking change ihtimaline karşı production’a almadan önce bekle.
  • Nerede kullanılır: form içi mantık için JS/Xrm.WebApi yerini koruyor; form dışı otomasyon, raporlama ve veri analizi script’leri için Python SDK gerçek bir kazanç — özellikle pandas ile birlikte.
  • Kimlik doğrulama farkı: form içinde oturum zaten açık; script’te InteractiveBrowserCredential (development) veya ClientSecretCredential (production, service principal) ile kendin açman gerekiyor.

Bu, Wave 1 ile gelen özellikleri D365 geliştiricisi gözünden ele aldığım kısa serinin ilk yazısı. Bir sonraki yazıda Dataverse MCP Server’a bakacağım.

Resmi Microsoft kaynakları

Kaynak kod / paket

Esenlikler.

Bu yazı işine yaradıysa paylaş
LinkedIn'de paylaş
SONRAKİ YAZI SharePoint’te Medya Kütüphanesi (Media Library) Oluşturma