Skip to content

Commit c5afb85

Browse files
ashleyvanspCopilot
andauthored
Fix delta external table schema diff, script syntax, and cleanup (#164)
* Fix delta external table schema diff, script syntax, and cleanup Three fixes for delta external tables: 1. Schema perpetual diff: The bulk loader populates the schema for all external tables from the cluster, but delta tables auto-infer their schema from the delta log — so YAML configs intentionally omit it. This caused a perpetual diff on every run. Fix: before comparing, clear the cluster-side schema for delta tables when the YAML doesn't specify one. If the YAML provides a custom schema, keep it for proper comparison. 2. Missing closing paren: CreateDeltaScript generated an unclosed parenthesis around the connection string, producing invalid KQL that fails Kusto syntax validation and cannot be applied. 3. Remove unnecessary dataFormat requirement: Delta tables don't use dataformat= in the Kusto command syntax. Removed the misleading validation that required it. 4. Only emit with() properties when set: Delta script no longer emits empty folder='', docString='', fileExtension='' when not specified in YAML. The with() block is omitted entirely if no properties are set. Fixes github/data#11973 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address comments --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 9587667 commit c5afb85

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

KustoSchemaTools/Changes/DatabaseChanges.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,22 @@ public static List<IChange> GenerateChanges(Database oldState, Database newState
113113
result.AddRange(mvChanges);
114114
result.AddRange(GenerateScriptCompareChanges(oldState, newState, db => db.ContinuousExports, nameof(newState.ContinuousExports), log));
115115
result.AddRange(GenerateScriptCompareChanges(oldState, newState, db => db.Functions, nameof(newState.Functions), log));
116+
117+
// For delta external tables, the schema is auto-inferred from the delta log.
118+
// If the YAML doesn't specify a schema, clear the cluster-side schema so it
119+
// doesn't cause a perpetual diff. If the YAML does specify a schema, keep the
120+
// cluster-side schema for proper comparison.
121+
foreach (var et in newState.ExternalTables)
122+
{
123+
if (et.Value.Kind?.ToLower() == "delta"
124+
&& et.Value.Schema?.Any() != true
125+
&& oldState.ExternalTables.TryGetValue(et.Key, out var oldExternalTable)
126+
&& oldExternalTable.Kind?.ToLower() == "delta")
127+
{
128+
oldExternalTable.Schema = null;
129+
}
130+
}
131+
116132
result.AddRange(GenerateScriptCompareChanges(oldState, newState, db => db.ExternalTables, nameof(newState.ExternalTables), log));
117133

118134
if (newState.EntityGroups.Any())

KustoSchemaTools/Model/ExternalTable.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ private string CreateSqlScript(string name)
137137

138138
private string CreateDeltaScript(string name)
139139
{
140-
if (string.IsNullOrWhiteSpace(DataFormat)) throw new ArgumentException("DataFormat can't be empty");
140+
if (string.IsNullOrWhiteSpace(ConnectionString)) throw new ArgumentException("ConnectionString can't be empty");
141141

142142
var sb = new StringBuilder();
143143
sb.AppendLine($".create-or-alter external table {name}");
@@ -146,11 +146,18 @@ private string CreateDeltaScript(string name)
146146
sb.AppendLine($"({string.Join(", ", Schema.Select(c => $"{c.Key.BracketIfIdentifier()}:{c.Value}"))})");
147147
}
148148
sb.AppendLine("kind=delta");
149-
sb.AppendLine($"(h@'{ConnectionString}'");
149+
sb.AppendLine($"(h@'{ConnectionString}')");
150150

151+
var withProps = new List<string>();
152+
if (!string.IsNullOrEmpty(Folder)) withProps.Add($"folder='{Folder}'");
153+
if (!string.IsNullOrEmpty(DocString)) withProps.Add($"docString='{DocString}'");
151154
var ext = string.IsNullOrWhiteSpace(FileExtensions) ? "" : FileExtensions.StartsWith(".") ? FileExtensions : "." + FileExtensions;
155+
if (!string.IsNullOrEmpty(ext)) withProps.Add($"fileExtension='{ext}'");
152156

153-
sb.AppendLine($"with(folder='{Folder}', docString='{DocString}', fileExtension='{ext}') ");
157+
if (withProps.Any())
158+
{
159+
sb.AppendLine($"with({string.Join(", ", withProps)})");
160+
}
154161

155162
return sb.ToString();
156163
}

0 commit comments

Comments
 (0)