Skip to content

Commit 9572375

Browse files
authored
feat: Allow skipping foreignkey constraint disablement for imports (n8n-io#25734)
1 parent 748b0aa commit 9572375

4 files changed

Lines changed: 53 additions & 5 deletions

File tree

packages/cli/src/commands/import/__tests__/entities.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ describe('ImportEntitiesCommand', () => {
3636
false,
3737
undefined,
3838
false,
39+
false,
3940
);
4041
});
4142

@@ -61,6 +62,7 @@ describe('ImportEntitiesCommand', () => {
6162
false,
6263
undefined,
6364
false,
65+
false,
6466
);
6567
});
6668

@@ -87,6 +89,7 @@ describe('ImportEntitiesCommand', () => {
8789
true,
8890
undefined,
8991
false,
92+
false,
9093
);
9194
});
9295

@@ -112,6 +115,7 @@ describe('ImportEntitiesCommand', () => {
112115
false,
113116
'key.txt',
114117
false,
118+
false,
115119
);
116120
});
117121

@@ -138,6 +142,34 @@ describe('ImportEntitiesCommand', () => {
138142
false,
139143
undefined,
140144
true,
145+
false,
146+
);
147+
});
148+
149+
it('should skip disabling foreign key constraints when skipTogglingForeignKeyConstraints flag is true', async () => {
150+
const command = new ImportEntitiesCommand();
151+
// @ts-expect-error Protected property
152+
command.flags = {
153+
inputDir: './outputs',
154+
truncateTables: false,
155+
skipTogglingForeignKeyConstraints: true,
156+
};
157+
// @ts-expect-error Protected property
158+
command.logger = {
159+
info: jest.fn(),
160+
error: jest.fn(),
161+
};
162+
163+
mockImportService.importEntities.mockResolvedValue(undefined);
164+
165+
await command.run();
166+
167+
expect(mockImportService.importEntities).toHaveBeenCalledWith(
168+
'./outputs',
169+
false,
170+
undefined,
171+
false,
172+
true,
141173
);
142174
});
143175

@@ -164,6 +196,7 @@ describe('ImportEntitiesCommand', () => {
164196
false,
165197
undefined,
166198
false,
199+
false,
167200
);
168201
});
169202

@@ -190,6 +223,7 @@ describe('ImportEntitiesCommand', () => {
190223
true,
191224
undefined,
192225
false,
226+
false,
193227
);
194228
});
195229
});

packages/cli/src/commands/import/entities.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ const flagsSchema = z.object({
2020
.boolean()
2121
.describe('Skip migration validation checks')
2222
.default(false),
23+
skipTogglingForeignKeyConstraints: z.coerce
24+
.boolean()
25+
.describe('Skip disabling foreign key constraints')
26+
.default(false),
2327
});
2428

2529
@Command({
@@ -44,6 +48,7 @@ export class ImportEntitiesCommand extends BaseCommand<z.infer<typeof flagsSchem
4448
const truncateTables = this.flags.truncateTables;
4549
const keyFilePath = this.flags.keyFile ? safeJoinPath(this.flags.keyFile) : undefined;
4650
const skipMigrationChecks = this.flags.skipMigrationChecks ?? false;
51+
const skipTogglingForeignKeyConstraints = this.flags.skipTogglingForeignKeyConstraints ?? false;
4752

4853
this.logger.info('\n⚠️⚠️ This feature is currently under development. ⚠️⚠️');
4954
this.logger.info('\n🚀 Starting entity import...');
@@ -52,12 +57,16 @@ export class ImportEntitiesCommand extends BaseCommand<z.infer<typeof flagsSchem
5257
if (skipMigrationChecks) {
5358
this.logger.info('⏭️ Skipping migration checks');
5459
}
60+
if (skipTogglingForeignKeyConstraints) {
61+
this.logger.info('⏭️ Skipping disabling foreign key constraints');
62+
}
5563

5664
await Container.get(ImportService).importEntities(
5765
inputDir,
5866
truncateTables,
5967
keyFilePath,
6068
skipMigrationChecks,
69+
skipTogglingForeignKeyConstraints,
6170
);
6271
}
6372

packages/cli/src/services/__tests__/import.service.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ describe('ImportService', () => {
559559
await importService.enableForeignKeyConstraints(mockEntityManager);
560560

561561
expect(mockEntityManager.query).toHaveBeenCalledWith(
562-
'SET session_replication_role = DEFAULT;',
562+
'SET session_replication_role = ORIGIN;',
563563
);
564564
});
565565
});

packages/cli/src/services/import.service.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ export class ImportService {
4444
sqlite: 'PRAGMA defer_foreign_keys = OFF;',
4545
'sqlite-pooled': 'PRAGMA defer_foreign_keys = OFF;',
4646
'sqlite-memory': 'PRAGMA defer_foreign_keys = OFF;',
47-
postgres: 'SET session_replication_role = DEFAULT;',
48-
postgresql: 'SET session_replication_role = DEFAULT;',
47+
postgres: 'SET session_replication_role = ORIGIN;',
48+
postgresql: 'SET session_replication_role = ORIGIN;',
4949
},
5050
};
5151

@@ -372,6 +372,7 @@ export class ImportService {
372372
truncateTables: boolean,
373373
keyFilePath?: string,
374374
skipMigrationChecks = false,
375+
skipTogglingForeignKeyConstraints = false,
375376
) {
376377
validateDbTypeForImportEntities(this.dataSource.options.type);
377378

@@ -397,7 +398,9 @@ export class ImportService {
397398
}
398399

399400
await this.dataSource.transaction(async (transactionManager: EntityManager) => {
400-
await this.disableForeignKeyConstraints(transactionManager);
401+
if (!skipTogglingForeignKeyConstraints) {
402+
await this.disableForeignKeyConstraints(transactionManager);
403+
}
401404

402405
// Get import metadata after migration validation
403406
const importMetadata = await this.getImportMetadata(inputDir);
@@ -434,7 +437,9 @@ export class ImportService {
434437
customEncryptionKey,
435438
);
436439

437-
await this.enableForeignKeyConstraints(transactionManager);
440+
if (!skipTogglingForeignKeyConstraints) {
441+
await this.enableForeignKeyConstraints(transactionManager);
442+
}
438443
});
439444

440445
// Cleanup decompressed files after import

0 commit comments

Comments
 (0)