Skip to content

Commit c299c97

Browse files
committed
feat: add DisableTargetIdentityInsertTables for tables where target has no identity
- Add per-table config DisableTargetIdentityInsertTables; when true, merge skips IDENTITY_INSERT (for target without identity column, source with). - Thread setting through SyncJobConfig, SyncJobTable, TableSchema and GetNewOrUpdatedMergeStatement. - Document in README (config table + note). - Suppress Azure SDK diagnostic logs in host.json (Azure.Core/Azure → Error). - Use collection expression for empty Tables in ProcessSyncJobService.
1 parent 534c240 commit c299c97

8 files changed

Lines changed: 24 additions & 10 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,15 @@ The function is configured through Azure App Settings / Environment variables, y
3232
| `SyncJobsConfig__Jobs__[key]__Manual` | Flag is sync excluded from schedules | `true` |
3333
| `SyncJobsConfig__Jobs__[key]__Schedules__[key]` | Optional opt-in/out schedules | `true` |
3434
| `SyncJobsConfig__Jobs__[key]__Tables__[key]` | Fully qualified name of table to sync | `dbo.MyTable` |
35+
| `SyncJobsConfig__Jobs__[key]__DisableTargetIdentityInsertTables__[key]` | Optional, per table. When `true`, merge does not use `IDENTITY_INSERT` on target (use when target has no identity column but source does). | `true` or `false` |
3536

3637

3738
> Note:
3839
>
3940
> Replace `[key]` with unique name of sync job / table config i.e. `MySync` / `MyTable` would result in `SyncJobsConfig__Jobs__MySync__Tables__MyTable`=`dbo.MyTable`
4041
>
42+
> **DisableTargetIdentityInsertTables**: Omit or set to `false` to copy identity values from source (default). Set to `true` per table when the target schema has no identity column but the source does.
43+
>
4144
> Configuration from KeyVault replace `__` with `--` i.e. `SyncJobsConfig--Jobs--MySync--Tables--MyTable`
4245
4346
## Schedules

src/SqlBulkSyncFunction/Helpers/SqlStatementExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ DROP TABLE {0}
5353
tableName
5454
);
5555

56-
public static string GetNewOrUpdatedMergeStatement(this TableSchema tableSchema)
56+
public static string GetNewOrUpdatedMergeStatement(this TableSchema tableSchema, bool disableTargetIdentityInsert)
5757
{
58-
var identityInsert = tableSchema.Columns.Any(column => column.IsIdentity);
58+
var identityInsert = !disableTargetIdentityInsert && tableSchema.Columns.Any(column => column.IsIdentity);
5959
var statement = string.Format(
6060
@"{6};
6161
MERGE {0} AS target

src/SqlBulkSyncFunction/Helpers/SyncJobConfigExtensions.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,23 @@ private static SyncJobTable[] ToSyncJobTables(this SyncJobConfig job)
3636
StringComparer.OrdinalIgnoreCase
3737
);
3838

39-
return job.Tables.Select(
39+
var disableTargetIdentityInsertTables = job.DisableTargetIdentityInsertTables?.ToLookup(
40+
key => key.Key,
41+
value => value.Value,
42+
StringComparer.OrdinalIgnoreCase
43+
);
44+
45+
return [.. job.Tables.Select(
4046
sourceTable => new SyncJobTable(
4147
sourceTable.Value,
4248
targetTableLookup?[sourceTable.Key].FirstOrDefault() switch
4349
{
4450
{ Length: > 0 } overrideTargetTable => overrideTargetTable,
4551
_ => sourceTable.Value
46-
}
52+
},
53+
disableTargetIdentityInsertTables?[sourceTable.Key].FirstOrDefault() ?? false
4754
)
48-
).ToArray();
55+
)];
4956
}
5057

5158
private static string TryGetToken(SyncJobConfigDataSource dataSource, ConcurrentDictionary<string, string> tokenCache) => dataSource.ManagedIdentity && tokenCache.TryGetValue(dataSource.TenantId ?? string.Empty, out var sourceToken)

src/SqlBulkSyncFunction/Models/Job/SyncJobConfig.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public record SyncJobConfig
88
public SyncJobConfigDataSource Target { get; init; }
99
public Dictionary<string, string> Tables { get; init; }
1010
public Dictionary<string, string> TargetTables { get; init; }
11+
public Dictionary<string, bool> DisableTargetIdentityInsertTables { get; init; }
1112
public int? BatchSize { get; init; }
1213
public string Area { get; init; }
1314
public bool? Manual { get; init; }
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
namespace SqlBulkSyncFunction.Models.Job
22
{
3-
public record SyncJobTable(string Source, string Target);
3+
public record SyncJobTable(string Source, string Target, bool DisableTargetIdentityInsert);
44
}

src/SqlBulkSyncFunction/Models/Schema/TableSchema.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public record TableSchema
2727
public TableVersion SourceVersion { get; }
2828
public TableVersion TargetVersion { get; }
2929
public int BatchSize { get; }
30+
public bool DisableTargetIdentityInsert { get; }
3031
private TableSchema(
3132
SyncJobTable table,
3233
Column[] columns,
@@ -45,6 +46,7 @@ private TableSchema(
4546

4647
SourceTableName = table.Source;
4748
TargetTableName = table.Target;
49+
DisableTargetIdentityInsert = table.DisableTargetIdentityInsert;
4850
SyncNewOrUpdatedTableName = FormattableString.Invariant($"sync.[{bufferName}_{DateTime.UtcNow:yyyyMMdd}_{targetVersion.CurrentVersion:00000000}_NewOrUpdated]");
4951
SyncDeletedTableName = FormattableString.Invariant($"sync.[{bufferName}_{DateTime.UtcNow:yyyyMMdd}_{targetVersion.CurrentVersion:00000000}_DeletedTable]");
5052
Columns = columns;
@@ -57,7 +59,7 @@ private TableSchema(
5759
SourceNewOrUpdatedSelectStatement = this.GetNewOrUpdatedAtSourceSelectStatement();
5860
SourceSelectAllStatement = this.GetSourceSelectAllStatement();
5961
SourceDeletedSelectStatement = this.GetDeletedAtSourceSelectStatement();
60-
MergeNewOrUpdateStatement = this.GetNewOrUpdatedMergeStatement();
62+
MergeNewOrUpdateStatement = this.GetNewOrUpdatedMergeStatement(DisableTargetIdentityInsert);
6163
DeleteStatement = this.GetDeleteStatement();
6264
DropNewOrUpdatedTableStatement = SyncNewOrUpdatedTableName.GetDropStatement();
6365
DropDeletedTableStatement = SyncDeletedTableName.GetDropStatement();

src/SqlBulkSyncFunction/Services/ProcessSyncJobService.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ public async Task ProcessSyncJob(SyncJob syncJob, bool globalChangeTracking)
5151
Logger.LogInformation("{Scope} Fetching table schemas...", scope);
5252
var schemaStopWatch = Stopwatch.StartNew();
5353
var tableSchemas = (
54-
syncJob.Tables
55-
?? Array.Empty<SyncJobTable>()
54+
syncJob.Tables ?? []
5655
)
5756
.Select(
5857
table => TableSchema.LoadSchema(

src/SqlBulkSyncFunction/host.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
"default": "Warning",
77
"Host.Results": "Warning",
88
"Function": "Warning",
9-
"Host.Aggregator": "Warning"
9+
"Host.Aggregator": "Warning",
10+
"Azure.Core": "Error",
11+
"Azure": "Error"
1012
},
1113
"applicationInsights": {
1214
"samplingSettings": {

0 commit comments

Comments
 (0)