Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Uyarı
Power Platform veri akışlarında gizlilik düzeyleri şu anda kullanılamıyor, ancak ürün ekibi bu işlevselliği etkinleştirmek için çalışıyor.
Power Query'yi herhangi bir süre kullandıysanız, büyük olasılıkla bunu yaşadınız. Bir anda, çevrimiçi aramalar, sorgu ayarlamaları veya klavye tuşlarına sertçe basmanın hiçbir şekilde düzeltemediği bir hatayla karşılaşıyorsunuz. Şuna benzer bir hata:
Formula.Firewall: Query 'Query1' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Veya belki:
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
Bu Formula.Firewall hatalar, Power Query'nin Veri Gizliliği Güvenlik Duvarı'nın (Güvenlik Duvarı olarak da bilinir) sonucu ortaya çıkabilir ve bu güvenlik duvarı bazen yalnızca veri analistlerini hayal kırıklığına uğratıyor gibi görünebilir. İster inanın ister inanmayın, ancak Güvenlik Duvarı önemli bir amaca hizmet eder. Bu makalede, nasıl çalıştığını daha iyi anlamak için arka planda araştırma yapacağız. Daha fazla anlayışla, gelecekte Güvenlik duvarı hatalarını daha iyi tanılayıp düzeltebilmenizi umuyoruz.
Nedir?
Veri Gizliliği Güvenlik Duvarı'nın amacı basittir: Power Query'nin yanlışlıkla kaynaklar arasında veri sızdırmasını önlemek için mevcuttur.
Bu neden gereklidir? Yani, OData akışına bir SQL değeri geçirebilecek bir M kodu yazabilirsiniz. Ancak bu kasıtlı veri sızıntısı olabilir. Karma yazarı bunu yaptığını bilir (veya en azından bunu yapmalıdır). O zaman neden istemeden veri sızıntısına karşı koruma ihtiyacı duyulsun?
Cevap mı? Katlanır.
Katlanıyor mu?
Katlama , M'deki ifadeleri (filtreler, yeniden adlandırmalar, birleştirmeler vb.) ham veri kaynağına (SQL, OData vb.) karşı işlemlere dönüştürmeyi ifade eden bir terimdir. Power Query'nin gücünün büyük bir kısmı, Power Query'nin kullanıcının kullanıcı arabirimi aracılığıyla gerçekleştirdiği işlemleri, kullanıcının söz konusu dilleri bilmesine gerek kalmadan karmaşık SQL veya diğer arka uç veri kaynağı dillerine dönüştürebildiği gerçeğinden kaynaklanabilir. Kullanıcılar yerel veri kaynağı işlemlerinin performans avantajını elde eder ve tüm veri kaynaklarının ortak bir komut kümesi kullanılarak dönüştürülebileceği bir kullanıcı arabiriminin kullanım kolaylığı sağlar.
Katlamanın bir parçası olarak Power Query bazen belirli bir karmayı yürütmenin en verimli yolunun verileri bir kaynaktan alıp diğerine geçirmek olduğunu belirleyebilir. Örneğin, küçük bir CSV dosyasını büyük bir SQL tablosuna katıyorsanız, büyük olasılıkla Power Query'nin CSV dosyasını okumasını, SQL tablosunun tamamını okumasını ve ardından bunları yerel bilgisayarınızda birleştirmesini istemezsiniz. Power Query'nin, CSV verilerini bir SQL ifadesine gömüp SQL veritabanında birleştirme işlemini gerçekleştirmesini isteyebilirsiniz.
İstenmeyen veri sızıntısı bu şekilde gerçekleşebilir.
Eğer çalışanların Sosyal Güvenlik Numaralarını içeren SQL verilerini dış bir OData akışının sonuçlarıyla birleştiriyor olsaydınız ve aniden SQL'den gelen Sosyal Güvenlik Numaralarının OData hizmetine gönderildiğini fark etseydiniz, düşünün. Kötü haber, değil mi?
Bu, Güvenlik Duvarı'nın önlemeyi amaçladığı senaryo türüdür.
Nasıl çalışır?
Güvenlik Duvarı, bir kaynaktan gelen verilerin istemeden başka bir kaynağa gönderilmesini önlemek için vardır. Yeterince basit.
Peki bu görevi nasıl başarıyor?
Bunu yapmak için M sorgularınızı bölümler adlı bir şeye böler ve sonra aşağıdaki kuralı zorunlu kılabilir:
- Bir bölüm uyumlu veri kaynaklarına erişebilir veya diğer bölümlere başvurabilir, ancak her ikisini birden başvuramayabilir.
Basit... ancak kafa karıştırıcı. Bölüm nedir? İki veri kaynağını "uyumlu" yapan nedir? Bir partition bir veri kaynağına erişmek ve bir partitiona referans almak istiyorsa Güvenlik Duvarı neden ilgilenmelidir?
Şimdi bunu parçalara ayıralım ve bir önceki kuralı parça parça inceleyelim.
Bölüm nedir?
En temel düzeyde, bir bölüt yalnızca bir veya daha fazla sorgu adımı toplamıdır. Mevcut uygulamada mümkün olan en ayrıntılı bölüm, tek bir adım seviyesindedir. En büyük bölümler bazen birden çok sorguyu kapsayabilir. (Daha sonra bu konu hakkında daha fazla bilgi edinin.)
Adımları bilmiyorsanız, bir sorgu seçtikten sonra Bunları Power Query Düzenleyicisi penceresinin sağ tarafında , Uygulanan Adımlar bölmesinde görüntüleyebilirsiniz. Adımlar, verilerinizi son şekline dönüştürmek için yaptığınız her şeyi takip eder.
Diğer bölümlere başvuran bölümler
Bir sorgu Güvenlik Duvarı açık olarak değerlendirildiğinde, Güvenlik Duvarı sorguyu ve tüm bağımlılıklarını bölümlere (yani adım gruplarına) böler. Her zaman bir bölüm başka bir bölümdeki bir öğeye başvurduğunda, Güvenlik Duvarı başvuruyu Value.Firewall adlı özel bir işlev çağrısı ile değiştirir. Başka bir deyişle, Güvenlik Duvarı bölümlerin birbirine doğrudan erişmesine izin vermez. Tüm referanslar, Güvenlik Duvarı üzerinden geçecek şekilde değiştirilmiştir. Güvenlik Duvarı'nı ağ geçidi denetleyicisi olarak düşünün. Başka bir bölüme başvuran bir bölüm, Güvenlik Duvarı'nın bunu yapma iznini almalıdır ve Güvenlik Duvarı, bölüme başvuruda bulunılan verilere izin verilip verilmeyeceğini denetler.
Bunların hepsi oldukça soyut görünebilir, bu nedenle bir örneğe göz atalım.
Sql veritabanından bazı verileri çeken Employees adlı bir sorgunuz olduğunu varsayalım. Ayrıca, basitçe Çalışanlar'ı referans alan başka bir sorgu (EmployeesReference) olduğunu varsayalım.
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Employees
in
Source;
Bu sorgular iki bölüme ayrılır: biri Çalışanlar sorgusu için, diğeri de EmployeesReference sorgusu için (Çalışanlar bölümüne başvurur). Güvenlik Duvarı açık olarak değerlendirildiğinde, bu sorgular şu şekilde yeniden yazılır:
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Value.Firewall("Section1/Employees")
in
Source;
Çalışanlar sorgusuna yapılan basit başvurunun, Çalışanlar sorgusunun tam adı sağlanarak yapılan bir çağrıyla Value.Firewall değiştirilmiş olduğuna dikkat edin.
EmployeesReference değerlendirildiğinde Güvenlik Duvarı, artık istenen verilerin EmployeesReference bölümüne akıp akmadığını ve nasıl akacağını kontrol etme şansına sahip olan Value.Firewall("Section1/Employees") çağrısına müdahale eder. Herhangi bir sayıda işlem yapabilir: isteği reddedebilir, istenen verileri arabelleğe alabilir (orijinal veri kaynağına geri dönülmesini önler) vb.
Güvenlik Duvarı, bölümler arasında akan veriler üzerinde bu şekilde denetim sahibidir.
Veri kaynaklarına doğrudan erişen bölümler
Sorgu1 sorgusunu tek adımla tanımladığınız (bu tek adımlı sorgu bir Güvenlik Duvarı bölümüne karşılık gelir) ve bu tek adımın iki veri kaynağına eriştiğine dikkat edin: SQL veritabanı tablosu ve CSV dosyası. Bölüm başvurusu olmadığından dolayı ve bu nedenle kesmesi için Value.Firewall çağrısı yapılmadığından, Güvenlik Duvarı bununla nasıl başa çıkmaktadır? Şimdi daha önce belirtilen kuralı gözden geçirelim:
- Bir bölüm uyumlu veri kaynaklarına erişebilir veya diğer bölümlere başvurabilir, ancak her ikisini birden başvurameyebilir.
Tek bölümlü ancak iki veri kaynağı sorgunuzun çalışmasına izin verilebilmesi için iki veri kaynağının "uyumlu" olması gerekir. Başka bir deyişle, verilerin bunlar arasında çift yönlü olarak paylaşılabilmesinin uygun olması gerekir. Bu, her iki kaynağın da gizlilik düzeylerinin Genel veya her ikisinin de Kurumsal olması gerektiği anlamına gelir, çünkü bunlar her iki yönde de paylaşıma izin veren tek iki birleşimdir. Her iki kaynak da Özel olarak işaretlenirse veya biri Genel, biri Kuruluş olarak işaretlenirse veya başka bir gizlilik düzeyleri bileşimi kullanılarak işaretlenirse, çift yönlü paylaşıma izin verilmez. İkisinin de aynı bölümde değerlendirilmesi güvenli değildir. Bunun yapılması güvenli olmayan veri sızıntısı gerçekleşebileceği anlamına gelir (katlama nedeniyle) ve Güvenlik Duvarı bunu önlemenin hiçbir yolu yoktur.
Aynı bölümdeki uyumsuz veri kaynaklarına erişmeye çalışırsanız ne olur?
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
Umarım bu makalenin başında listelenen hata iletilerinden birini daha iyi anlarsınız.
Bu uyumluluk gereksinimi yalnızca belirli bir bölüm içinde geçerlidir. Bir bölüm diğer bölümlere başvuruyorsa, başvuruda bulunılan bölümlerdeki veri kaynaklarının birbiriyle uyumlu olması gerekmez. Bunun nedeni, Güvenlik Duvarı'nın verileri arabelleğe alabilir ve bu da özgün veri kaynağına daha fazla katlanmasını önler. Veriler belleğe yüklenir ve hiçbir yerden gelmiş gibi değerlendirilir.
Neden ikisini de yapmayasın?
Bir başka iki sorguya (yani, iki başka bölüme) erişen bir adım (bir bölüme karşılık gelen) ile bir sorgu tanımladığınızı varsayalım. Aynı adımda bir SQL veritabanına doğrudan erişmek isterseniz ne olur? Bölüm neden diğer bölümlere başvuramıyor ve uyumlu veri kaynaklarına doğrudan erişemiyor?
Daha önce gördüğünüz gibi, bir bölüm başka bir bölüme başvurduğunda, Güvenlik Duvarı bölüme akan tüm veriler için ağ geçidi denetleyicisi işlevi görür. Bunu yapmak için, hangi verilere izin verileceğini kontrol edebilmelidir. Bölme içinde erişilen veri kaynakları varsa ve diğer bölmelerden veri akışı yapılıyorsa, içeri akan veriler içeride erişilen veri kaynaklarından birine haber olmadan sızdırılabileceğinden bekçi olma özelliğini kaybeder. Bu nedenle Güvenlik Duvarı, diğer bölümlere erişen bir bölümün herhangi bir veri kaynağına doğrudan erişmesine izin verilmemesini önler.
Peki bir bölüm diğer bölümlere başvurmaya ve veri kaynaklarına doğrudan erişmeye çalışırsa ne olur?
Formula.Firewall: Query 'Query1' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Artık bu makalenin başında listelenen diğer hata iletisini daha iyi anlayacağınızı umuyoruz.
Ayrıntılı bölümler
Önceki bilgilerden tahmin edebilirsiniz, sorguların nasıl bölümlendiği inanılmaz derecede önemli olur. Diğer sorgulara başvuran bazı adımlarınız ve veri kaynaklarına erişen diğer adımlarınız varsa, artık bölüm sınırlarını belirli yerlerde çizmenin Güvenlik duvarı hatalarına neden olduğunu ve bunları başka yerlerde çizmenin sorgunuzun düzgün çalışmasına olanak tanıdığını umuyoruz.
Peki sorgular tam olarak nasıl bölümlenebilir?
Bu bölüm, güvenlik duvarı hatalarını neden gördüğünüzu anlamak ve bunların nasıl çözüleceğini (mümkün olduğunda) anlamak için büyük olasılıkla en önemli bölümdür.
Bölümleme mantığının üst düzey bir özeti aşağıda verilmiştır.
- İlk Bölümleme
- Her sorgudaki her adım için bir bölüm oluşturur
- Statik Aşama
- Bu aşama değerlendirme sonuçlarına bağlı değildir. Bunun yerine sorguların nasıl yapılandırıldığına bağlıdır.
- Parametre Kesme
- Parametre benzeri bölümlerin herhangi birini, yani şunu kırpıyor:
- Diğer bölümlere atıfta bulunmaz
- İşlev çağrıları içermez
- Döngüsel değildir (yani kendisini referans almaz)
- Bir bölümün "kaldırılması" durumunda, o bölümün referans verdiği diğer bölümlere dahil edildiğini unutmayın.
- Parametre bölümlerini kırpmak, "bölüm veri kaynaklarına ve diğer adımlara başvuramıyor" hataları yerine, veri kaynağı işlev çağrılarında (örneğin,
Web.Contents(myUrl)) kullanılan parametre referanslarının düzgün çalışmasını sağlar.
- Parametre benzeri bölümlerin herhangi birini, yani şunu kırpıyor:
- Gruplandırma (Statik)
- Bölümler, aşağıdan yukarıya bağımlılık sırasına göre birleştirilir. Sonuçta elde edilen birleştirilmiş bölümlerde aşağıdakiler ayrıdır:
- Farklı sorgulardaki bölüntüler
- Diğer bölümlere bağlantı kurmayan bölümler (ve bu nedenle de bir veri kaynağına erişmelerine izin verilir)
- Diğer bölümlere başvuran bölümler (ve bu nedenle veri kaynağına erişmesi yasaktır)
- Bölümler, aşağıdan yukarıya bağımlılık sırasına göre birleştirilir. Sonuçta elde edilen birleştirilmiş bölümlerde aşağıdakiler ayrıdır:
- Parametre Kesme
- Bu aşama değerlendirme sonuçlarına bağlı değildir. Bunun yerine sorguların nasıl yapılandırıldığına bağlıdır.
- Dinamik Aşama
- Bu aşama, çeşitli bölümler tarafından erişilen veri kaynakları hakkındaki bilgiler de dahil olmak üzere değerlendirme sonuçlarına bağlıdır.
- Kesme
- Tüm aşağıdaki gereksinimleri karşılayan bölümler kırpılır:
- Hiçbir veri kaynağına erişmez
- Veri kaynaklarına erişen bölümlere başvurmaz
- Döngüsel değil
- Tüm aşağıdaki gereksinimleri karşılayan bölümler kırpılır:
- Gruplandırma (Dinamik)
- Artık gereksiz bölümler kırpıldığından, mümkün olduğunca büyük Kaynak bölümleri oluşturmayı deneyin. Bu oluşturma işlemi, önceki statik gruplandırma aşamasında açıklanan kuralların aynısını kullanarak bölümleri birleştirerek gerçekleştirilir.
Tüm bunlar ne anlama geliyor?
Şimdi daha önce ortaya konan karmaşık mantığın nasıl çalıştığını göstermek için bir örneği inceleyelim.
Örnek bir senaryo aşağıda verilmiştır. Bir metin dosyasının (Kişiler) SQL veritabanı (Çalışanlar) ile oldukça basit bir şekilde birleştirilmesidir ve BURADA SQL sunucusu bir parametredir (DbServer).
Üç sorgu
Bu örnekte kullanılan üç sorgunun M kodu aşağıda verilmiştır.
shared DbServer = "MySqlServer" meta [IsParameterQuery=true, Type="Text", IsParameterQueryRequired=true];
shared Contacts = let
Source = Csv.Document(File.Contents(
"C:\contacts.txt"),[Delimiter=" ", Columns=15, Encoding=1252, QuoteStyle=QuoteStyle.None]
),
#"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
#"Changed Type" = Table.TransformColumnTypes(
#"Promoted Headers",
{
{"ContactID", Int64.Type},
{"NameStyle", type logical},
{"Title", type text},
{"FirstName", type text},
{"MiddleName", type text},
{"LastName", type text},
{"Suffix", type text},
{"EmailAddress", type text},
{"EmailPromotion", Int64.Type},
{"Phone", type text},
{"PasswordHash", type text},
{"PasswordSalt", type text},
{"AdditionalContactInfo", type text},
{"rowguid", type text},
{"ModifiedDate", type datetime}
}
)
in
#"Changed Type";
shared Employees = let
Source = Sql.Databases(DbServer),
AdventureWorks = Source{[Name="AdventureWorks"]}[Data],
HumanResources_Employee = AdventureWorks{[Schema="HumanResources",Item="Employee"]}[Data],
#"Removed Columns" = Table.RemoveColumns(
HumanResources_Employee,
{
"HumanResources.Employee(EmployeeID)",
"HumanResources.Employee(ManagerID)",
"HumanResources.EmployeeAddress",
"HumanResources.EmployeeDepartmentHistory",
"HumanResources.EmployeePayHistory",
"HumanResources.JobCandidate",
"Person.Contact",
"Purchasing.PurchaseOrderHeader",
"Sales.SalesPerson"
}
),
#"Merged Queries" = Table.NestedJoin(
#"Removed Columns",
{"ContactID"},
Contacts,
{"ContactID"},
"Contacts",
JoinKind.LeftOuter
),
#"Expanded Contacts" = Table.ExpandTableColumn(
#"Merged Queries",
"Contacts",
{"EmailAddress"},
{"EmailAddress"}
)
in
#"Expanded Contacts";
Bağımlılıkları gösteren daha üst düzey bir görünüm aşağıdadır.
Bölümleyelim
Biraz yakınlaştıralım ve resme adımları ekleyelim ve bölümleme mantığında gezinmeye başlayalım. İlk güvenlik duvarı bölümlerini yeşil olarak gösteren üç sorgunun diyagramı aşağıdadır. Her adımın kendi bölümünde başladığına dikkat edin.
Ardından parametre bölümlerini kırpacağız. Bu nedenle, DbServer örtük olarak Kaynak bölümüne eklenir.
Şimdi statik gruplandırma gerçekleştiriyoruz. Bu gruplandırma, ayrı sorgulardaki bölümler (örneğin, Çalışanların son iki adımının Kişiler adımlarıyla gruplandırılamadığını unutmayın) ve diğer bölümlere başvuran bölümler (Çalışanların son iki adımı gibi) ile olmayan bölümler (Çalışanların ilk üç adımı gibi) arasında ayrım sağlar.
Şimdi dinamik aşamaya giriyoruz. Bu aşamada, yukarıdaki statik bölümler değerlendirilir. Hiçbir veri kaynağına erişmeyen bölümler kırpılır. Ardından bölümler, mümkün olduğunca büyük kaynak bölümler oluşturmak için gruplandırılır. Ancak, bu örnek senaryoda, kalan tüm bölümler veri kaynaklarına erişiyor ve gerçekleştirilebilecek başka gruplandırma yok. Bu nedenle örneğimizdeki bölümler bu aşamada değişmez.
Hadi rol yapalım.
Ancak çizim açısından, bir metin dosyasından gelmek yerine Kişiler sorgusunun M'de sabit kodlanmış olması durumunda (belki de Verileri Girin iletişim kutusu aracılığıyla) neler olabileceğine bakalım.
Bu durumda, Kişiler sorgusu hiçbir veri kaynağına erişemez. Böylece, dinamik fazın ilk bölümünde kırpılacaktır.
Kişiler bölümü kaldırıldıktan sonra, Çalışanlar bölümünün son iki adımı, Çalışanlar'ın ilk üç adımını içeren bölüm dışındaki hiçbir bölüme atıfta bulunmaz. Bu nedenle, iki bölüm gruplandırılır.
Sonuçta elde edilen bölüm şöyle görünür.
Örnek: Bir veri kaynağından diğerine veri geçirme
Tamam, bu kadar soyut açıklama yeter. Güvenlik duvarı hatasıyla karşılaşma olasılığınız olan yaygın bir senaryoya ve bunu çözme adımlarına göz atalım.
Northwind OData hizmetinden bir şirket adı aramak ve ardından Bing araması yapmak için şirket adını kullanmak istediğinizi düşünün.
İlk olarak, şirket adını almak için bir Şirket sorgusu oluşturursunuz.
let
Source = OData.Feed(
"https://services.odata.org/V4/Northwind/Northwind.svc/",
null,
[Implementation="2.0"]
),
Customers_table = Source{[Name="Customers",Signature="table"]}[Data],
CHOPS = Customers_table{[CustomerID="CHOPS"]}[CompanyName]
in
CHOPS
Ardından, Arama sorgusu oluşturur, Şirket'e başvurarak Bing'e iletirsiniz.
let
Source = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & Company))
in
Source
Bu noktada, başın belaya girer. Arama'nın değerlendirilmesi bir Güvenlik Duvarı hatası oluşturur.
Formula.Firewall: Query 'Search' (step 'Source') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Bu hatanın nedeni , Arama'nın Kaynak adımının bir veri kaynağına (bing.com) başvurması ve ayrıca başka bir sorguya/bölüme (Şirket) başvurmasıdır. Daha önce bahsedilen kuralı ihlal ediyor ("bir bölüm uyumlu veri kaynaklarına erişebilir veya diğer bölümlere başvurabilir, ancak her ikisini birden erişemez").
Ne yapmalı? Bir seçenek, Güvenlik Duvarı'nı tamamen devre dışı bırakmaktır ( Gizlilik Düzeylerini Yoksay ve potansiyel olarak performansı geliştirin etiketli Gizlilik seçeneği aracılığıyla). Peki ya Güvenlik Duvarı'nı etkin bırakmak istiyorsanız?
Güvenlik Duvarı'nı devre dışı bırakmadan hatayı çözmek için Şirket ve Arama'yı tek bir sorguda birleştirebilirsiniz, örneğin:
let
Source = OData.Feed(
"https://services.odata.org/V4/Northwind/Northwind.svc/",
null,
[Implementation="2.0"]
),
Customers_table = Source{[Name="Customers",Signature="table"]}[Data],
CHOPS = Customers_table{[CustomerID="CHOPS"]}[CompanyName],
Search = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & CHOPS))
in
Search
Artık her şey tek bir bölümde gerçekleşiyor. İki veri kaynağının gizlilik seviyelerinin uyumlu olduğunu varsayarsak, Güvenlik Duvarı artık düzgün çalışmalıdır ve bir hata almazsınız.
İşimiz bitti.
Bu konuda söylenebilecek çok daha fazla şey olsa da, bu giriş makalesi zaten yeterince uzun. Umarım güvenlik duvarını daha iyi anlamanıza yardımcı olur ve gelecekte karşılaştığınızda Güvenlik Duvarı hatalarını anlamanıza ve düzeltmenize yardımcı olur.