หมายเหตุ
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลอง ลงชื่อเข้าใช้หรือเปลี่ยนไดเรกทอรีได้
การเข้าถึงหน้านี้ต้องได้รับการอนุญาต คุณสามารถลองเปลี่ยนไดเรกทอรีได้
Note
ขณะนี้ระดับความเป็นส่วนตัวไม่พร้อมใช้งานในกระแสข้อมูล Power Platform แต่ทีมผลิตภัณฑ์กําลังทํางานเพื่อเปิดใช้งานฟังก์ชันนี้
หากคุณใช้ Power Query เป็นระยะเวลานาน คุณอาจประสบปัญหานี้ คุณกําลังสืบค้นเมื่อจู่ๆ คุณก็ได้รับข้อผิดพลาดที่การค้นหาออนไลน์ การปรับแต่งแบบสอบถาม หรือการทุบตีแป้นพิมพ์ไม่สามารถแก้ไขได้ ข้อผิดพลาดเช่น:
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.
หรืออาจจะ:
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
ข้อผิดพลาดเหล่านี้ Formula.Firewall เป็นผลมาจากไฟร์วอลล์ความเป็นส่วนตัวของข้อมูลของ Power Query (หรือที่เรียกว่าไฟร์วอลล์) ซึ่งในบางครั้งอาจดูเหมือนว่ามีอยู่เพื่อทําให้นักวิเคราะห์ข้อมูลทั่วโลกหงุดหงิดเท่านั้น อย่างไรก็ตาม เชื่อหรือไม่ว่าไฟร์วอลล์มีจุดประสงค์ที่สําคัญ ในบทความนี้ เราจะเจาะลึกลงไปเพื่อทําความเข้าใจวิธีการทํางานให้ดียิ่งขึ้น ด้วยความเข้าใจที่มากขึ้น หวังว่าคุณจะสามารถวินิจฉัยและแก้ไขข้อผิดพลาดของไฟร์วอลล์ได้ดีขึ้นในอนาคต
นี่อะไรน่ะ
วัตถุประสงค์ของไฟร์วอลล์ความเป็นส่วนตัวของข้อมูลนั้นง่ายมาก: มีไว้เพื่อป้องกันไม่ให้ Power Query รั่วไหลของข้อมูลระหว่างแหล่งข้อมูลโดยไม่ได้ตั้งใจ
เหตุใดจึงจำเป็น ฉันหมายความว่าคุณสามารถเขียน M ที่จะส่งค่า SQL ไปยังฟีด OData ได้อย่างแน่นอน แต่นี่จะเป็นการรั่วไหลของข้อมูลโดยเจตนา ผู้เขียน mashup จะ (หรืออย่างน้อยก็ควร) รู้ว่าพวกเขากําลังทําสิ่งนี้ เหตุใดจึงจําเป็นต้องป้องกันการรั่วไหลของข้อมูลโดยไม่ได้ตั้งใจ
คําตอบ? พับ
พับ
การพับเป็น คําที่อ้างถึงการแปลงนิพจน์ใน M (เช่น ตัวกรอง การเปลี่ยนชื่อ การรวม และอื่นๆ) เป็นการดําเนินการกับแหล่งข้อมูลดิบ (เช่น SQL, OData และอื่นๆ) พลังส่วนใหญ่ของ Power Query มาจากข้อเท็จจริงที่ว่า Power Query สามารถแปลงการดําเนินการที่ผู้ใช้ดําเนินการผ่านส่วนติดต่อผู้ใช้เป็น SQL ที่ซับซ้อนหรือภาษาแหล่งข้อมูลแบ็กเอนด์อื่นๆ โดยที่ผู้ใช้ไม่จําเป็นต้องรู้ภาษาดังกล่าว ผู้ใช้จะได้รับประโยชน์ด้านประสิทธิภาพของการดําเนินการแหล่งข้อมูลดั้งเดิม ด้วยความง่ายในการใช้งาน UI ที่แหล่งข้อมูลทั้งหมดสามารถแปลงได้โดยใช้ชุดคําสั่งทั่วไป
ในฐานะที่เป็นส่วนหนึ่งของการพับ บางครั้ง Power Query อาจกําหนดว่าวิธีที่มีประสิทธิภาพที่สุดในการดําเนินการ Mashup ที่กําหนดคือการนําข้อมูลจากแหล่งหนึ่งและส่งต่อไปยังอีกแหล่งหนึ่ง ตัวอย่างเช่น ถ้าคุณกําลังรวมไฟล์ CSV ขนาดเล็กเข้ากับตาราง SQL ขนาดใหญ่ คุณอาจไม่ต้องการให้ Power Query อ่านไฟล์ CSV อ่านตาราง SQL ทั้งหมด แล้วรวมเข้าด้วยกันบนคอมพิวเตอร์ภายในเครื่องของคุณ คุณอาจต้องการให้ Power Query อินไลน์ข้อมูล CSV ลงในคําสั่ง SQL และขอให้ฐานข้อมูล SQL ดําเนินการรวม
นี่คือวิธีที่การรั่วไหลของข้อมูลโดยไม่ได้ตั้งใจสามารถเกิดขึ้นได้
ลองนึกภาพถ้าคุณกําลังรวมข้อมูล SQL ที่มีหมายเลขประกันสังคมของพนักงานกับผลลัพธ์ของตัวดึงข้อมูล OData ภายนอก และจู่ๆ คุณก็พบว่าหมายเลขประกันสังคมจาก SQL ถูกส่งไปยังบริการ OData ข่าวร้ายใช่มั้ย?
นี่คือสถานการณ์ที่ไฟร์วอลล์มีจุดประสงค์เพื่อป้องกัน
ขั้นตอนการทํางาน
ไฟร์วอลล์มีไว้เพื่อป้องกันไม่ให้ข้อมูลจากแหล่งหนึ่งถูกส่งไปยังแหล่งอื่นโดยไม่ได้ตั้งใจ ง่ายพอสมควร
แล้วมันทําภารกิจนี้ให้สําเร็จได้อย่างไร?
ทําได้โดยการแบ่งแบบสอบถาม M ของคุณออกเป็นสิ่งที่เรียกว่าพาร์ติชัน แล้วบังคับใช้กฎต่อไปนี้:
- พาร์ติชันอาจเข้าถึงแหล่งข้อมูลที่เข้ากันได้ หรืออ้างอิงพาร์ติชันอื่น แต่ไม่ใช่ทั้งสองอย่าง
ง่าย ยังสับสน พาร์ติชันคืออะไร? อะไรทําให้แหล่งข้อมูลสองแหล่ง "เข้ากันได้" และเหตุใดไฟร์วอลล์จึงควรใส่ใจหากพาร์ติชันต้องการเข้าถึงแหล่งข้อมูลและอ้างอิงพาร์ติชัน
ลองแยกย่อยและดูกฎก่อนหน้านี้ทีละชิ้น
พาร์ติชันคืออะไร?
ในระดับพื้นฐานที่สุดพาร์ติชันเป็นเพียงคอลเลกชันของขั้นตอนคิวรีอย่างน้อยหนึ่งขั้นตอน พาร์ติชันที่ละเอียดที่สุดเท่าที่จะเป็นไปได้ (อย่างน้อยก็ในการใช้งานปัจจุบัน) เป็นขั้นตอนเดียว พาร์ติชันที่ใหญ่ที่สุดบางครั้งอาจครอบคลุมการสืบค้นหลายรายการ (เพิ่มเติมเกี่ยวกับเรื่องนี้ในภายหลัง)
ถ้าคุณไม่คุ้นเคยกับขั้นตอน คุณสามารถดูขั้นตอนเหล่านั้นได้ทางด้านขวาของหน้าต่างตัวแก้ไข Power Query หลังจากเลือกคิวรี ในบานหน้าต่าง ขั้นตอนที่ใช้ ขั้นตอนจะติดตามทุกสิ่งที่คุณทําเพื่อแปลงข้อมูลของคุณให้เป็นรูปร่างสุดท้าย
พาร์ติชันที่อ้างอิงพาร์ติชันอื่น
เมื่อมีการประเมินแบบสอบถามโดยเปิดไฟร์วอลล์ ไฟร์วอลล์จะแบ่งแบบสอบถามและการขึ้นต่อกันทั้งหมดออกเป็นพาร์ติชัน (นั่นคือกลุ่มของขั้นตอน) เมื่อใดก็ตามที่พาร์ติชันหนึ่งอ้างอิงบางสิ่งในอีกพาร์ติชันหนึ่งไฟร์วอลล์จะแทนที่การอ้างอิงด้วยการเรียกฟังก์ชันพิเศษที่เรียกว่า Value.Firewall. กล่าวอีกนัยหนึ่งไฟร์วอลล์ไม่อนุญาตให้พาร์ติชันเข้าถึงกันได้โดยตรง การอ้างอิงทั้งหมดจะถูกแก้ไขให้ผ่านไฟร์วอลล์ คิดว่าไฟร์วอลล์เป็นผู้เฝ้าประตู พาร์ติชันที่อ้างอิงพาร์ติชันอื่นต้องได้รับอนุญาตจากไฟร์วอลล์เพื่อทําเช่นนั้น และไฟร์วอลล์จะควบคุมว่าข้อมูลที่อ้างอิงจะได้รับอนุญาตในพาร์ติชันหรือไม่
ทั้งหมดนี้อาจดูเป็นนามธรรม ดังนั้นเรามาดูตัวอย่างกัน
สมมติว่าคุณมีแบบสอบถามที่เรียกว่า พนักงาน ซึ่งจะดึงข้อมูลบางอย่างจากฐานข้อมูล SQL สมมติว่าคุณมีแบบสอบถามอื่น (EmployeesReference) ซึ่งอ้างอิงเพียง Employees
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Employees
in
Source;
คิวรีเหล่านี้จะแบ่งออกเป็นสองพาร์ติชัน: พาร์ติชันหนึ่งสําหรับคิวรี Employees และอีกพาร์ติชันหนึ่งสําหรับคิวรี EmployeesReference (ซึ่งอ้างอิงพาร์ติชัน Employees) เมื่อประเมินโดยเปิดไฟร์วอลล์ แบบสอบถามเหล่านี้จะถูกเขียนใหม่ดังนี้:
shared Employees = let
Source = Sql.Database(…),
EmployeesTable = …
in
EmployeesTable;
shared EmployeesReference = let
Source = Value.Firewall("Section1/Employees")
in
Source;
โปรดสังเกตว่าการอ้างอิงอย่างง่ายไปยังคิวรี พนักงาน จะถูกแทนที่ด้วยการเรียก Value.Firewallไปยัง ซึ่งมีชื่อเต็มของคิวรี พนักงาน
เมื่อมีการประเมิน EmployeesReference ไฟร์วอลล์จะสกัดกั้นการเรียกไปยัง Value.Firewall("Section1/Employees")ซึ่งตอนนี้มีโอกาสที่จะควบคุมว่า (และอย่างไร) ข้อมูลที่ร้องขอจะไหลเข้าสู่พาร์ติชัน EmployeesReference หรือไม่ สามารถทําสิ่งต่างๆ ได้หลายอย่าง: ปฏิเสธคําขอ บัฟเฟอร์ข้อมูลที่ร้องขอ (ซึ่งป้องกันไม่ให้เกิดการพับไปยังแหล่งข้อมูลเดิม) และอื่นๆ
นี่คือวิธีที่ไฟร์วอลล์รักษาการควบคุมข้อมูลที่ไหลระหว่างพาร์ติชัน
พาร์ติชันที่เข้าถึงแหล่งข้อมูลโดยตรง
สมมติว่าคุณกําหนดคิวรี Query1 ด้วยขั้นตอนเดียว (โปรดทราบว่าคิวรีขั้นตอนเดียวนี้สอดคล้องกับพาร์ติชันไฟร์วอลล์หนึ่งพาร์ติชัน) และขั้นตอนเดียวนี้เข้าถึงแหล่งข้อมูลสองแหล่ง: ตารางฐานข้อมูล SQL และไฟล์ CSV ไฟร์วอลล์จัดการกับเรื่องนี้อย่างไร เนื่องจากไม่มีการอ้างอิงพาร์ติชัน ดังนั้นจึงไม่มีการเรียกใช้ Value.Firewall เพื่อสกัดกั้น ลองทบทวนกฎที่ระบุไว้ก่อนหน้านี้:
- พาร์ติชันสามารถเข้าถึงแหล่งข้อมูลที่เข้ากันได้ หรืออ้างอิงพาร์ติชันอื่นๆ แต่ไม่สามารถเข้าถึงทั้งสองอย่างได้
เพื่อให้คิวรีพาร์ติชันเดียว แต่สองแหล่งข้อมูลของคุณได้รับอนุญาตให้เรียกใช้แหล่งข้อมูลสองแหล่งจะต้อง "เข้ากันได้" กล่าวอีกนัยหนึ่งก็คือต้องโอเคสําหรับข้อมูลที่จะแบ่งปันแบบสองทิศทางระหว่างกัน ซึ่งหมายความว่าระดับความเป็นส่วนตัวของทั้งสองแหล่งที่มาจะต้องเป็นสาธารณะ หรือทั้งสองอย่างเป็นองค์กร เนื่องจากนี่เป็นชุดค่าผสมเพียงสองแบบที่อนุญาตให้แชร์ได้ทั้งสองทิศทาง หากแหล่งที่มาทั้งสองถูกทําเครื่องหมายว่าเป็นส่วนตัว หรือแหล่งที่มาหนึ่งถูกทําเครื่องหมายว่าสาธารณะ และอีกแหล่งหนึ่งถูกทําเครื่องหมายว่าเป็นองค์กร หรือมีการทําเครื่องหมายโดยใช้ระดับความเป็นส่วนตัวแบบผสมผสานกัน ไม่ปลอดภัยสําหรับทั้งคู่ที่จะได้รับการประเมินในพาร์ติชันเดียวกัน การทําเช่นนี้หมายความว่าการรั่วไหลของข้อมูลที่ไม่ปลอดภัยอาจเกิดขึ้นได้ (เนื่องจากการพับ) และไฟร์วอลล์จะไม่มีทางป้องกันได้
จะเกิดอะไรขึ้นหากคุณพยายามเข้าถึงแหล่งข้อมูลที่เข้ากันไม่ได้ในพาร์ติชันเดียวกัน
Formula.Firewall: Query 'Query1' (step 'Source') is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.
หวังว่าตอนนี้คุณจะเข้าใจข้อความแสดงข้อผิดพลาดที่ระบุไว้ในตอนต้นของบทความนี้ได้ดีขึ้น
ข้อกําหนด ความเข้ากันได้ นี้ใช้เฉพาะภายในพาร์ติชันที่กําหนดเท่านั้น ถ้าพาร์ติชันอ้างอิงพาร์ติชันอื่น แหล่งข้อมูลจากพาร์ติชันที่อ้างอิงไม่จําเป็นต้องเข้ากันได้ เนื่องจากไฟร์วอลล์สามารถบัฟเฟอร์ข้อมูล ซึ่งจะป้องกันการพับเพิ่มเติมกับแหล่งข้อมูลเดิม ข้อมูลจะถูกโหลดลงในหน่วยความจําและถือว่ามาจากไหนก็ไม่รู้
ทําไมไม่ทําทั้งสองอย่างล่ะ?
สมมติว่าคุณกําหนดคิวรีด้วยขั้นตอนเดียว (ซึ่งสอดคล้องกับพาร์ติชันเดียวอีกครั้ง) ที่เข้าถึงคิวรีอีกสองรายการ (นั่นคือ อีกสองพาร์ติชัน) จะเกิดอะไรขึ้นถ้าคุณต้องการเข้าถึงฐานข้อมูล SQL โดยตรงในขั้นตอนเดียวกัน เหตุใดพาร์ติชันจึงไม่สามารถอ้างอิงพาร์ติชันอื่นและเข้าถึงแหล่งข้อมูลที่เข้ากันได้โดยตรง
ดังที่คุณเห็นก่อนหน้านี้เมื่อพาร์ติชันหนึ่งอ้างอิงพาร์ติชันอื่นไฟร์วอลล์จะทําหน้าที่เป็นผู้รักษาประตูสําหรับข้อมูลทั้งหมดที่ไหลเข้าสู่พาร์ติชัน ในการทําเช่นนั้น จะต้องสามารถควบคุมข้อมูลที่ได้รับอนุญาตได้ หากมีแหล่งข้อมูลที่เข้าถึงได้ภายในพาร์ติชัน และข้อมูลที่ไหลเข้ามาจากพาร์ติชันอื่น ๆ จะสูญเสียความสามารถในการเป็นผู้เฝ้าประตู เนื่องจากข้อมูลที่ไหลเข้ามาอาจรั่วไหลไปยังแหล่งข้อมูลที่เข้าถึงภายในแหล่งใดแหล่งหนึ่งโดยไม่รู้ตัว ดังนั้นไฟร์วอลล์จึงป้องกันไม่ให้พาร์ติชันที่เข้าถึงพาร์ติชันอื่นได้รับอนุญาตให้เข้าถึงแหล่งข้อมูลใด ๆ ได้โดยตรง
จะเกิดอะไรขึ้นหากพาร์ติชันพยายามอ้างอิงพาร์ติชันอื่นและเข้าถึงแหล่งข้อมูลโดยตรง
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.
ตอนนี้หวังว่าคุณจะเข้าใจข้อความแสดงข้อผิดพลาดอื่น ๆ ที่ระบุไว้ในตอนต้นของบทความนี้ได้ดีขึ้น
พาร์ติชันในเชิงลึก
อย่างที่คุณอาจเดาได้จากข้อมูลก่อนหน้านี้วิธีการแบ่งพาร์ติชันแบบสอบถามมีความสําคัญอย่างไม่น่าเชื่อ หากคุณมีขั้นตอนบางอย่างที่อ้างอิงคิวรีอื่น ๆ และขั้นตอนอื่น ๆ ที่เข้าถึงแหล่งข้อมูลตอนนี้คุณหวังว่าจะตระหนักดีว่าการวาดขอบเขตพาร์ติชันในบางที่ทําให้เกิดข้อผิดพลาดของไฟร์วอลล์ในขณะที่การวาดในที่อื่นจะช่วยให้คิวรีของคุณทํางานได้ดี
แล้วแบบสอบถามจะถูกแบ่งพาร์ติชันได้อย่างไร?
ส่วนนี้อาจเป็นส่วนที่สําคัญที่สุดสําหรับการทําความเข้าใจว่าเหตุใดคุณจึงเห็นข้อผิดพลาดของไฟร์วอลล์ และทําความเข้าใจวิธีแก้ไข (หากเป็นไปได้)
นี่คือบทสรุประดับสูงของตรรกะการแบ่งพาร์ติชัน
- การแบ่งพาร์ติชันเริ่มต้น
- สร้างพาร์ติชันสําหรับแต่ละขั้นตอนในแต่ละแบบสอบถาม
- เฟสคงที่
- ขั้นตอนนี้ไม่ได้ขึ้นอยู่กับผลการประเมิน แต่จะขึ้นอยู่กับโครงสร้างของคิวรีแทน
- การตัดแต่งพารามิเตอร์
- ตัดแต่งพาร์ติชันแบบพารามิเตอร์นั่นคือพาร์ติชันใด ๆ ที่:
- ไม่อ้างอิงพาร์ติชันอื่น ๆ
- ไม่มีการเรียกใช้ฟังก์ชันใดๆ
- ไม่ใช่วัฏจักร (นั่นคือไม่ได้อ้างถึงตัวเอง)
- โปรดทราบว่า "การลบ" พาร์ติชันจะรวมพาร์ติชันนั้นไว้ในพาร์ติชันอื่น ๆ ที่อ้างอิงอย่างมีประสิทธิภาพ
- การตัดแต่งพาร์ติชันพารามิเตอร์ช่วยให้การอ้างอิงพารามิเตอร์ที่ใช้ภายในการเรียกฟังก์ชันแหล่งข้อมูล (ตัวอย่างเช่น
Web.Contents(myUrl)) ทํางาน แทนที่จะส่งข้อผิดพลาด "พาร์ติชันไม่สามารถอ้างอิงแหล่งข้อมูลและขั้นตอนอื่นๆ"
- ตัดแต่งพาร์ติชันแบบพารามิเตอร์นั่นคือพาร์ติชันใด ๆ ที่:
- การจัดกลุ่ม (คงที่)
- พาร์ติชันจะถูกรวมตามลําดับการขึ้นต่อกันจากล่างขึ้นบน ในพาร์ติชันที่ผสานผลลัพธ์ต่อไปนี้จะแยกจากกัน:
- พาร์ติชันในแบบสอบถามต่างๆ
- พาร์ติชันที่ไม่อ้างอิงพาร์ติชันอื่น (และได้รับอนุญาตให้เข้าถึงแหล่งข้อมูล)
- พาร์ติชันที่อ้างอิงพาร์ติชันอื่น (และห้ามไม่ให้เข้าถึงแหล่งข้อมูล)
- พาร์ติชันจะถูกรวมตามลําดับการขึ้นต่อกันจากล่างขึ้นบน ในพาร์ติชันที่ผสานผลลัพธ์ต่อไปนี้จะแยกจากกัน:
- การตัดแต่งพารามิเตอร์
- ขั้นตอนนี้ไม่ได้ขึ้นอยู่กับผลการประเมิน แต่จะขึ้นอยู่กับโครงสร้างของคิวรีแทน
- เฟสไดนามิก
- ขั้นตอนนี้ขึ้นอยู่กับผลการประเมิน รวมถึงข้อมูลเกี่ยวกับแหล่งข้อมูลที่เข้าถึงโดยพาร์ติชันต่างๆ
- การตัดแต่ง
- ตัดแต่งพาร์ติชันที่ตรงตามข้อกําหนดต่อไปนี้ทั้งหมด:
- ไม่เข้าถึงแหล่งข้อมูลใดๆ
- ไม่อ้างอิงพาร์ติชันใดๆ ที่เข้าถึงแหล่งข้อมูล
- ไม่เป็นวัฏจักร
- ตัดแต่งพาร์ติชันที่ตรงตามข้อกําหนดต่อไปนี้ทั้งหมด:
- การจัดกลุ่ม (ไดนามิก)
- ตอนนี้พาร์ติชันที่ไม่จําเป็นถูกตัดแต่งแล้วให้ลองสร้างพาร์ติชันต้นทางที่มีขนาดใหญ่ที่สุด การสร้างนี้ทําได้โดยการรวมพาร์ติชันโดยใช้กฎเดียวกันกับที่อธิบายไว้ในขั้นตอนการจัดกลุ่มแบบคงที่ก่อนหน้านี้
ทั้งหมดนี้หมายความว่าอย่างไร?
ลองดูตัวอย่างเพื่อแสดงให้เห็นว่าตรรกะที่ซับซ้อนที่วางไว้ก่อนหน้านี้ทํางานอย่างไร
นี่คือสถานการณ์ตัวอย่าง เป็นการผสานไฟล์ข้อความ (ผู้ติดต่อ) กับฐานข้อมูล SQL (พนักงาน) ที่ค่อนข้างตรงไปตรงมา โดยที่เซิร์ฟเวอร์ SQL เป็นพารามิเตอร์ (DbServer)
คําถามทั้งสาม
นี่คือโค้ด M สําหรับคิวรีสามแบบที่ใช้ในตัวอย่างนี้
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";
นี่คือมุมมองระดับที่สูงขึ้นซึ่งแสดงการขึ้นต่อกัน
มาแบ่งพาร์ติชันกันเถอะ
ลองซูมเข้าเล็กน้อยและรวมขั้นตอนในภาพและเริ่มเดินผ่านตรรกะการแบ่งพาร์ติชัน นี่คือไดอะแกรมของแบบสอบถามทั้งสามที่แสดงพาร์ติชันไฟร์วอลล์เริ่มต้นเป็นสีเขียว โปรดสังเกตว่าแต่ละขั้นตอนเริ่มต้นในพาร์ติชันของตัวเอง
ต่อไปเราตัดแต่งพาร์ติชันพารามิเตอร์ ดังนั้น DbServer จึงรวมอยู่ในพาร์ติชันต้นทางโดยปริยาย
ตอนนี้เราทําการจัดกลุ่มแบบคงที่ การจัดกลุ่มนี้จะรักษาการแยกระหว่างพาร์ติชันในแบบสอบถามที่แยกต่างหาก (ตัวอย่างเช่น โปรดทราบว่าสองขั้นตอนสุดท้ายของพนักงานจะไม่ถูกจัดกลุ่มด้วยขั้นตอนของผู้ติดต่อ) และระหว่างพาร์ติชันที่อ้างอิงพาร์ติชันอื่น (เช่น สองขั้นตอนสุดท้ายของพนักงาน) และพาร์ติชันที่ไม่ได้อ้างอิง (เช่น สามขั้นตอนแรกของพนักงาน)
ตอนนี้เราเข้าสู่ช่วงไดนามิก ในขั้นตอนนี้พาร์ติชันแบบคงที่ข้างต้นจะได้รับการประเมิน พาร์ติชันที่ไม่เข้าถึงแหล่งข้อมูลใดๆ จะถูกตัดแต่ง พาร์ติชันจะถูกจัดกลุ่มเพื่อสร้างพาร์ติชันต้นทางที่มีขนาดใหญ่ที่สุดเท่าที่จะเป็นไปได้ อย่างไรก็ตาม ในสถานการณ์ตัวอย่างนี้ พาร์ติชันที่เหลือทั้งหมดเข้าถึงแหล่งข้อมูล และไม่มีการจัดกลุ่มเพิ่มเติมที่สามารถทําได้ พาร์ติชันในตัวอย่างของเราจึงไม่เปลี่ยนแปลงในระหว่างขั้นตอนนี้
มาแกล้งทําเป็นกันเถอะ
เพื่อประโยชน์ของภาพประกอบ เรามาดูกันว่าจะเกิดอะไรขึ้นหากคิวรีผู้ติดต่อ แทนที่จะมาจากไฟล์ข้อความ ถูกฮาร์ดโค้ดใน M (อาจผ่านกล่องโต้ตอบ ป้อนข้อมูล )
ในกรณีนี้ คิวรีผู้ติดต่อจะไม่เข้าถึงแหล่งข้อมูลใดๆ ดังนั้นมันจะถูกตัดแต่งในช่วงแรกของเฟสไดนามิก
เมื่อนําพาร์ติชันผู้ติดต่อออก สองขั้นตอนสุดท้ายของพนักงานจะไม่อ้างอิงพาร์ติชันใดๆ อีกต่อไป ยกเว้นพาร์ติชันที่มีสามขั้นตอนแรกของพนักงาน ดังนั้นพาร์ติชันทั้งสองจะถูกจัดกลุ่ม
พาร์ติชันที่ได้จะมีลักษณะดังนี้
ตัวอย่าง: การส่งผ่านข้อมูลจากแหล่งข้อมูลหนึ่งไปยังอีกแหล่งข้อมูลหนึ่ง
โอเค คําอธิบายที่เป็นนามธรรมเพียงพอ ลองดูสถานการณ์ทั่วไปที่คุณมีแนวโน้มที่จะพบข้อผิดพลาดของไฟร์วอลล์และขั้นตอนในการแก้ไข
ลองนึกภาพว่าคุณต้องการค้นหาชื่อบริษัทจากบริการ Northwind OData แล้วใช้ชื่อบริษัทเพื่อทําการค้นหา Bing
ขั้นแรก คุณสร้างแบบสอบถาม บริษัท เพื่อเรียกชื่อบริษัท
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
ถัดไป คุณสร้างแบบสอบถาม การค้นหา ที่อ้างอิง บริษัท และส่งต่อไปยัง Bing
let
Source = Text.FromBinary(Web.Contents("https://www.bing.com/search?q=" & Company))
in
Source
ณ จุดนี้ คุณประสบปัญหา การประเมิน การค้นหา ทําให้เกิดข้อผิดพลาดไฟร์วอลล์
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.
ข้อผิดพลาดนี้เกิดขึ้นเนื่องจากขั้นตอน แหล่งที่มา ของ การค้นหา กําลังอ้างอิงแหล่งข้อมูล (bing.com) และยังอ้างอิงแบบสอบถาม/พาร์ติชันอื่น (บริษัท) เป็นการละเมิดกฎที่กล่าวถึงก่อนหน้านี้ ("พาร์ติชันสามารถเข้าถึงแหล่งข้อมูลที่เข้ากันได้ หรืออ้างอิงพาร์ติชันอื่น ๆ แต่ไม่ใช่ทั้งสองอย่าง")
จะทําอย่างไร? ทางเลือกหนึ่งคือการปิดใช้งานไฟร์วอลล์ทั้งหมด (ผ่านตัวเลือกความเป็นส่วนตัวที่ระบุว่า ละเว้นระดับความเป็นส่วนตัวและอาจปรับปรุงประสิทธิภาพ) แต่ถ้าคุณต้องการเปิดใช้งานไฟร์วอลล์ทิ้งไว้ล่ะ?
เมื่อต้องการแก้ไขข้อผิดพลาดโดยไม่ปิดใช้งานไฟร์วอลล์ คุณสามารถรวม บริษัท และ การค้นหา เป็นแบบสอบถามเดียว ดังนี้
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
ตอนนี้ทุกอย่างกําลังเกิดขึ้นภายในพาร์ติชันเดียว สมมติว่าระดับความเป็นส่วนตัวสําหรับแหล่งข้อมูลทั้งสองเข้ากันได้ไฟร์วอลล์ควรจะมีความสุขและคุณจะไม่ได้รับข้อผิดพลาดอีกต่อไป
นั่นคือบทสรุป
แม้ว่าจะมีอะไรอีกมากมายที่สามารถพูดได้ในหัวข้อนี้ แต่บทความเบื้องต้นนี้ก็ยาวพอแล้ว หวังว่ามันจะช่วยให้คุณเข้าใจไฟร์วอลล์ได้ดีขึ้น และช่วยให้คุณเข้าใจและแก้ไขข้อผิดพลาดของไฟร์วอลล์เมื่อคุณพบในอนาคต