diff --git a/KustoSchemaTools/Changes/DatabaseChanges.cs b/KustoSchemaTools/Changes/DatabaseChanges.cs index 0770927..068066e 100644 --- a/KustoSchemaTools/Changes/DatabaseChanges.cs +++ b/KustoSchemaTools/Changes/DatabaseChanges.cs @@ -113,6 +113,22 @@ public static List GenerateChanges(Database oldState, Database newState result.AddRange(mvChanges); result.AddRange(GenerateScriptCompareChanges(oldState, newState, db => db.ContinuousExports, nameof(newState.ContinuousExports), log)); result.AddRange(GenerateScriptCompareChanges(oldState, newState, db => db.Functions, nameof(newState.Functions), log)); + + // For delta external tables, the schema is auto-inferred from the delta log. + // If the YAML doesn't specify a schema, clear the cluster-side schema so it + // doesn't cause a perpetual diff. If the YAML does specify a schema, keep the + // cluster-side schema for proper comparison. + foreach (var et in newState.ExternalTables) + { + if (et.Value.Kind?.ToLower() == "delta" + && et.Value.Schema?.Any() != true + && oldState.ExternalTables.TryGetValue(et.Key, out var oldExternalTable) + && oldExternalTable.Kind?.ToLower() == "delta") + { + oldExternalTable.Schema = null; + } + } + result.AddRange(GenerateScriptCompareChanges(oldState, newState, db => db.ExternalTables, nameof(newState.ExternalTables), log)); if (newState.EntityGroups.Any()) diff --git a/KustoSchemaTools/Model/ExternalTable.cs b/KustoSchemaTools/Model/ExternalTable.cs index 11bc7d3..d85768a 100644 --- a/KustoSchemaTools/Model/ExternalTable.cs +++ b/KustoSchemaTools/Model/ExternalTable.cs @@ -137,7 +137,7 @@ private string CreateSqlScript(string name) private string CreateDeltaScript(string name) { - if (string.IsNullOrWhiteSpace(DataFormat)) throw new ArgumentException("DataFormat can't be empty"); + if (string.IsNullOrWhiteSpace(ConnectionString)) throw new ArgumentException("ConnectionString can't be empty"); var sb = new StringBuilder(); sb.AppendLine($".create-or-alter external table {name}"); @@ -146,11 +146,18 @@ private string CreateDeltaScript(string name) sb.AppendLine($"({string.Join(", ", Schema.Select(c => $"{c.Key.BracketIfIdentifier()}:{c.Value}"))})"); } sb.AppendLine("kind=delta"); - sb.AppendLine($"(h@'{ConnectionString}'"); + sb.AppendLine($"(h@'{ConnectionString}')"); + var withProps = new List(); + if (!string.IsNullOrEmpty(Folder)) withProps.Add($"folder='{Folder}'"); + if (!string.IsNullOrEmpty(DocString)) withProps.Add($"docString='{DocString}'"); var ext = string.IsNullOrWhiteSpace(FileExtensions) ? "" : FileExtensions.StartsWith(".") ? FileExtensions : "." + FileExtensions; + if (!string.IsNullOrEmpty(ext)) withProps.Add($"fileExtension='{ext}'"); - sb.AppendLine($"with(folder='{Folder}', docString='{DocString}', fileExtension='{ext}') "); + if (withProps.Any()) + { + sb.AppendLine($"with({string.Join(", ", withProps)})"); + } return sb.ToString(); }