針對倉庫開發的 Git 整合問題

適用於: ✅ Microsoft Fabric 中的倉庫

本文包含開發與部署Fabric Data Warehouse與 Fabric內建 Git 整合的故障排除主題。

Important

這項功能目前處於預覽階段。

使用三部分名稱來參考倉庫自身的物件

一個物件可以透過使用三部分名稱 來參考同一倉庫中的另一個物件。 [warehouse_name].[schema_name].[object_name]

三部分命名是用來指代 不同的 倉庫。 當資料庫部分命名目前倉庫時,建置會將該參考視為外部,物件在模型中被定義兩次。

將資料庫部分從倉庫自身物件的引用中移除:

-- Fails: the warehouse is named MyWarehouse and references itself by name
CREATE VIEW [Sales].[CustomerSummary] AS
SELECT c.[CustomerId], c.[OrderDate]
FROM [MyWarehouse].[Sales].[Customers] AS c;

-- Works
CREATE VIEW [Sales].[CustomerSummary] AS
SELECT c.[CustomerId], c.[OrderDate]
FROM [Sales].[Customers] AS c;

只需要更改對倉庫自身物件的參考。 支援真正的跨資料庫參照,指向其他倉庫,例如 [Other_Warehouse].[Sales].[Orders],且應保持 as-is。

Important

僅在跨倉庫或跨 SQL 分析端點參考時使用三段命名database.schema.object(),而非同一倉庫內的物件。 在同一倉庫中用三段命名來自我參照物件並非標準建模做法,且可能產生無意間的外部參考。

在可能的情況下,使用兩部分命名(schema.object)而非三部分命名來建模物件,即使是在同一倉庫內的自參照。 此慣例提升了客戶工具間的一致性,並避免了三段式引用所帶來的歧義。

Git 倉庫中過時的 .sqlproj

Git 儲存庫可以包含 .sqlproj 參考較舊 Microsoft.Build.Sql SDK 版本的檔案。 舊版 SDK 不支援較新的 Fabric Data Warehouse 語法,例如IDENTITY欄位和 CLUSTER BY。

此問題影響於倉庫轉換為現行定義格式前已提交內容的儲存庫。 最常見的情況會導致 .sqlproj 檔案過時的情況包括:

  • 將新工作區連接到現有的儲存庫。 倉庫是由那裡所承諾的物品所創造的。
  • 嘗試拓展到新的工作空間。
  • 從 Git 還原已刪除的倉庫。
  • 在倉庫轉換到目前定義格式後,立即從 Git 同步,且還沒完成任何相反方向的同步。

沒有移到目前定義格式的倉庫不會受影響,因為舊專案檔案不會被用來建置。

如何確認 .sqlproj SDK 版本

在倉庫中打開倉庫 .sqlproj 檔案,檢查 XML 中的 SDK 版本:

<Sdk Name="Microsoft.Build.Sql" Version="2.2.0" />

這個版本落後於現有的 Microsoft。Build.SQL 套件版本表示專案檔案已過時。 例如,如果你的版本以 開頭。0.1. 欲了解更多資訊,請參閱 Microsoft。Build.SQL 與範本版本。

更新 .sqlproj SDK 版本選項 A:先同步倉庫到 Git。

如果倉庫已經存在於工作區且運作良好,請先從工作區提交到 Git,再往相反方向同步。 此操作會以目前的 SDK 版本重新生成專案檔案,之後從 Git 同步即可正常運作。

此選項在有時較為推薦,因為它能更新整個定義,而不只是 SDK 屬性。

倉庫必須已經是目前的定義格式,這個選項才會有效。 如果沒有,先在 Fabric Git 面板升級,然後再承諾 Git。 從仍使用舊定義格式的倉庫提交,會將舊格式寫回倉庫,且不會刷新 SDK 版本,因此下一次同步也會以同樣方式失敗。 如果無法升級,建議改用 修正選項B 。

更新 .sqlproj SDK 版本選項 B:直接在 Git 中更新 .sqlproj 檔案

當倉庫尚未在目標工作區中存在時,例如將新工作區連結到現有倉庫、分支或還原已刪除的倉庫時,請使用此選項。 在這些情況下,沒有倉庫可以同步,所以無法使用修正選項 A。

編輯.sqlproj倉庫中的檔案,使用最新的 Microsoft。Build.Sql 套件版本並提交變更。 例如:

<!-- Before -->
<Sdk Name="Microsoft.Build.Sql" Version="0.1.19-preview" />

<!-- After -->
<Sdk Name="Microsoft.Build.Sql" Version="2.2.0" />

單獨執行匯出或差異檔並不會更新專案檔案。 只有當工作區提交到 Git 完成,或是手動編輯時,檔案才會被重寫。

物件中不限定欄位,若參考其他倉庫中兩個或以上資料表

在 T-SQL 查詢中引用欄位時,務必提供並使用資料表別名。

  • 當 T-SQL 查詢參考另一個倉庫中的兩個或多個資料表時,建置無法驗證沒有資料表別名的欄位。 表格不需要共用欄位名稱,這種歧義才會存在。 這種模糊性存在於驗證建構中。
  • 這種模糊性影響了在同一語句主體中,參考兩個或以上其他倉庫資料表的物件內的 T-SQL 查詢。
  • 這種模糊性不會影響只參考另一個倉庫中一個資料表的物件內的 T-SQL 查詢,因為單一來源之間就沒有歧義。
  • 這種模糊性不會影響完全集中在單一倉庫內的 T-SQL 查詢。

以下範例中,只有 fieldinfo , finame因此 SQL 對倉庫有效且能正確執行,但驗證建置中存在歧義。

-- Fails: two tables from another warehouse, and 'finame' isn't alias-qualified
CREATE PROCEDURE [dbo].[LoadFieldInfo] AS
SELECT finame
FROM   [OtherWarehouse].[halo].[fieldinfo] AS f
INNER JOIN   [OtherWarehouse].[halo].[lookup]    AS l ON f.[id] = l.[id];

在受影響物件的每個欄位參考中,新增一個表格別名:

-- Works: every column carries its table alias
CREATE PROCEDURE [dbo].[LoadFieldInfo] AS
SELECT f.[finame]
FROM   [OtherWarehouse].[halo].[fieldinfo] AS f
INNER JOIN   [OtherWarehouse].[halo].[lookup]    AS l ON f.[id] = l.[id];

模式名稱大寫不一致

你的倉庫可以使用不區分大小寫的排序,所以 sales 和 Sales 是同一個結構,但你的腳本可能在不同地方拼出兩種方式。 案例不敏感的資料庫一直接受這種說法,因此這種不一致通常是長期存在且無害的。

當你的腳本在另一個倉庫的同一個架構中引用兩個或以上不同的物件,並且每個參考中對該架構拼寫不同時,建置會 CREATE SCHEMA 為每個拼寫產生一個陳述。 此問題僅影響那些參考另一倉庫並使用大小寫不區分的整合的倉庫。

  • 預設情況下,Fabric 中的倉庫使用 Latin1_General_100_BIN2_UTF8,這是一種大小寫區分的彙整。 案件敏感的倉庫則不受影響。 在這些倉庫裡, sales 不 Sales 管你是否有意,都是兩種不同的結構。
  • 一個大小寫不區分的資料庫無法同時包含 sales 和 Sales。 重複只是因為你 SQL 文本中的拼寫不同。

請檢查倉庫的整合資料和檔案中ModelCollation指定的資料.sqlproj。 請尋找( CI 不區分大小寫)或 CS (以大寫為區分)的狀態。

<ModelCollation>1033, CI</ModelCollation>   <!-- case-insensitive: affected -->
<ModelCollation>1033, CS</ModelCollation>   <!-- case-sensitive: not affected -->

修復

要找出倉庫物件定義中結構名稱大小寫不一致的情況,可以比較所有腳本錯誤中模式大小寫的情況。 找兩個跨倉庫的參考,指向同一架構,只是在萬一情況下不同。

在所有地方使用一致的大寫,並且與參考倉庫中的實際結構名稱相符。 例如,只使用 Sales 或 sales。

-- Fails: two objects in the same schema, referenced with different capitalization
CREATE VIEW [dbo].[v_one] AS SELECT * FROM [OtherWarehouse].[sales].[Orders];
GO
CREATE VIEW [dbo].[v_two] AS SELECT * FROM [OtherWarehouse].[Sales].[Customers];

-- Works: same capitalization in both references
CREATE VIEW [dbo].[v_one] AS SELECT * FROM [OtherWarehouse].[Sales].[Orders];
GO
CREATE VIEW [dbo].[v_two] AS SELECT * FROM [OtherWarehouse].[Sales].[Customers];

當你有兩個不同的物件,且有兩種不同的結構大小寫時,就會遇到這個問題。 對 同一 物件的兩個不同大小寫參考會正確摺疊且不會失敗。

欄位對照

如果欄位的COLLATE子句明確指定與倉庫預設排序相同的排序,Fabric 的結構擷取(基於 DacFx 的)會將明確排序視為完全不指定排序。 在這種情況下:

  • 這個明確 COLLATE 子句不會出現在提取到 Git 倉庫的項目定義中。
  • 該欄位在 Git 變更、 更新或部署管線比較中不會顯示為差異,因為與倉庫預設的整合並無實質差異。

只有與倉庫預設排序不同的欄位,在原始碼控制中保留 COLLATE 明確的子句,且只有這些欄位整合的變更會被視為差異。

例如,考慮一個倉庫,其排序為 Latin1_General_100_CI_AS_KS_WS_SC_UTF8:

CREATE TABLE dbo.MixedCollationExample
(
    CustomerId      INT             NOT NULL,
    FirstName       VARCHAR(100)    NOT NULL,                                               -- inherits warehouse collation
    LastNameBin     VARCHAR(100)    COLLATE Latin1_General_100_BIN2_UTF8 NOT NULL,          -- column override, differs from warehouse collation
    Email           VARCHAR(256)    COLLATE Latin1_General_100_CI_AS_KS_WS_SC_UTF8 NULL     -- explicit collation, matches warehouse collation
);
  • FirstName 沒有明確的整合,並繼承倉庫的預設整合。
  • LastNameBin 有明確的排序,與倉庫的預設排序不同,因此它會保留在擷取的定義中,且如果有變動,它總會出現在比較中。
  • Email 有明確的整合,與倉庫的預設整合相符。 即使這個 COLLATE 子句存在於 T-SQL 中,它卻不會出現在 Git 提取的定義或 Git 或部署流程比較中,因為它等同於預設值。

含重複候選物件的歧義欄位錯誤

從 Git 提交或更新可能會因欄位錯誤而失敗,該錯誤的候選清單包含 :: 分隔符,例如:

SQL71501: View: [dbo].[SchoolSummary] contains an unresolved reference to an object.
Either the object does not exist or the reference is ambiguous because it could refer
to any of the following objects: [dbo].[SchoolSummary].[NCESID] or
[dbo].[SchoolSummary].[ss]::[NCESID].

::分隔符將此錯誤與指向兩個或以上資料表的物件中未限定欄位所描述的真實歧義區分開來。 新增表格別名並不會解決問題,因為別名會出現在候選列表中,錯誤仍然存在。

  1. 首先,排除以下兩個較常見的原因:

    • 一個真正缺失或被誤稱的物品。 如果同一提交或更新同時回報了對特定遺失物件的未解決參考,例如 SQL71501: View: [dbo].[v_report] has an unresolved reference to object [dbo].[MissingTable],請先修正該參考。 ::候選人通常也會跟著通過。
    • 一篇真正模糊不清的專欄。 如果在兩個來源的連接上選擇了一個未限定欄位,而這兩個來源都暴露了該欄位,則以表格別名(例如 a.[NCESID])來限定該欄位。 SQL Server 也會拒絕這個查詢,所以這不是 Git 整合特有的問題。
  2. 如果每個被參考的物件都存在,且沒有任何欄位是真正模糊的,候 :: 選物件就是驗證過程中已知的問題,該驗證在提交和更新過程中執行,由產品團隊追蹤。 請依序嘗試以下這些變通方法:

    1. 在 CTE 和導出資料表內,替換 SELECT * 成明確的欄位清單。
    2. 將視圖拆分,使每個模糊來源在獨立視圖中定義,並參考該視圖,避免重複底層查詢。
    3. 避免在同一語句中與 OPENROWSET(BULK ...) 另一個動態形狀的來源連接。

若這些方法皆無法解決錯誤,請收集錯誤中指定的物件定義並 開啟支援請求。 關於部署管線的具體限制,請參見 限制。