diff --git a/packages/@n8n/db/src/entities/execution-data.ts b/packages/@n8n/db/src/entities/execution-data.ts index 3134b2b107f..55a1454a4f8 100644 --- a/packages/@n8n/db/src/entities/execution-data.ts +++ b/packages/@n8n/db/src/entities/execution-data.ts @@ -27,6 +27,9 @@ export class ExecutionData { @PrimaryColumn({ transformer: idStringifier }) executionId: string; + @Column({ type: 'varchar', length: 36, nullable: true }) + workflowVersionId: string | null; + @OneToOne('ExecutionEntity', 'executionData', { onDelete: 'CASCADE', }) diff --git a/packages/@n8n/db/src/migrations/common/1765892199653-AddVersionIdToExecutionData.ts b/packages/@n8n/db/src/migrations/common/1765892199653-AddVersionIdToExecutionData.ts new file mode 100644 index 00000000000..1644a90c995 --- /dev/null +++ b/packages/@n8n/db/src/migrations/common/1765892199653-AddVersionIdToExecutionData.ts @@ -0,0 +1,11 @@ +import type { MigrationContext, ReversibleMigration } from '../migration-types'; + +export class AddWorkflowVersionIdToExecutionData1765892199653 implements ReversibleMigration { + async up({ schemaBuilder: { addColumns, column } }: MigrationContext) { + await addColumns('execution_data', [column('workflowVersionId').varchar(36)]); + } + + async down({ schemaBuilder: { dropColumns } }: MigrationContext) { + await dropColumns('execution_data', ['workflowVersionId']); + } +} diff --git a/packages/@n8n/db/src/migrations/mysqldb/index.ts b/packages/@n8n/db/src/migrations/mysqldb/index.ts index a4892c7a4c6..9d539a63e75 100644 --- a/packages/@n8n/db/src/migrations/mysqldb/index.ts +++ b/packages/@n8n/db/src/migrations/mysqldb/index.ts @@ -127,6 +127,7 @@ import { BackfillMissingWorkflowHistoryRecords1765448186933 } from '../common/17 import { AddResolvableFieldsToCredentials1765459448000 } from '../common/1765459448000-AddResolvableFieldsToCredentials'; import { AddIconToAgentTable1765788427674 } from '../common/1765788427674-AddIconToAgentTable'; import { AddAgentIdForeignKeys1765886667897 } from '../common/1765886667897-AddAgentIdForeignKeys'; +import { AddWorkflowVersionIdToExecutionData1765892199653 } from '../common/1765892199653-AddVersionIdToExecutionData'; import type { Migration } from '../migration-types'; export const mysqlMigrations: Migration[] = [ @@ -259,4 +260,5 @@ export const mysqlMigrations: Migration[] = [ AddResolvableFieldsToCredentials1765459448000, AddIconToAgentTable1765788427674, AddAgentIdForeignKeys1765886667897, + AddWorkflowVersionIdToExecutionData1765892199653, ]; diff --git a/packages/@n8n/db/src/migrations/postgresdb/index.ts b/packages/@n8n/db/src/migrations/postgresdb/index.ts index 8d811e1cca7..108b218e678 100644 --- a/packages/@n8n/db/src/migrations/postgresdb/index.ts +++ b/packages/@n8n/db/src/migrations/postgresdb/index.ts @@ -128,6 +128,7 @@ import { BackfillMissingWorkflowHistoryRecords1765448186933 } from '../common/17 import { AddResolvableFieldsToCredentials1765459448000 } from '../common/1765459448000-AddResolvableFieldsToCredentials'; import { AddIconToAgentTable1765788427674 } from '../common/1765788427674-AddIconToAgentTable'; import { AddAgentIdForeignKeys1765886667897 } from '../common/1765886667897-AddAgentIdForeignKeys'; +import { AddWorkflowVersionIdToExecutionData1765892199653 } from '../common/1765892199653-AddVersionIdToExecutionData'; import type { Migration } from '../migration-types'; export const postgresMigrations: Migration[] = [ @@ -261,4 +262,5 @@ export const postgresMigrations: Migration[] = [ AddIconToAgentTable1765788427674, ConvertAgentIdToUuid1765804780000, AddAgentIdForeignKeys1765886667897, + AddWorkflowVersionIdToExecutionData1765892199653, ]; diff --git a/packages/@n8n/db/src/migrations/sqlite/index.ts b/packages/@n8n/db/src/migrations/sqlite/index.ts index 2e4a6383c2b..8d451343bd0 100644 --- a/packages/@n8n/db/src/migrations/sqlite/index.ts +++ b/packages/@n8n/db/src/migrations/sqlite/index.ts @@ -123,6 +123,7 @@ import { CreateDynamicCredentialResolverTable1764682447000 } from '../common/176 import { AddDynamicCredentialEntryTable1764689388394 } from '../common/1764689388394-AddDynamicCredentialEntryTable'; import { BackfillMissingWorkflowHistoryRecords1765448186933 } from '../common/1765448186933-BackfillMissingWorkflowHistoryRecords'; import { AddIconToAgentTable1765788427674 } from '../common/1765788427674-AddIconToAgentTable'; +import { AddWorkflowVersionIdToExecutionData1765892199653 } from '../common/1765892199653-AddVersionIdToExecutionData'; import type { Migration } from '../migration-types'; const sqliteMigrations: Migration[] = [ @@ -251,6 +252,7 @@ const sqliteMigrations: Migration[] = [ AddResolvableFieldsToCredentials1764689448000, AddIconToAgentTable1765788427674, AddAgentIdForeignKeys1765886667897, + AddWorkflowVersionIdToExecutionData1765892199653, ]; export { sqliteMigrations }; diff --git a/packages/@n8n/db/src/repositories/execution.repository.ts b/packages/@n8n/db/src/repositories/execution.repository.ts index 5387a667ce4..fb99291f988 100644 --- a/packages/@n8n/db/src/repositories/execution.repository.ts +++ b/packages/@n8n/db/src/repositories/execution.repository.ts @@ -367,7 +367,12 @@ export class ExecutionRepository extends Repository { // In the non-pooling sqlite driver we can't use transactions, because that creates nested transactions under highly concurrent loads, leading to errors in the database const { identifiers: inserted } = await this.insert({ ...rest, createdAt: new Date() }); const { id: executionId } = inserted[0] as { id: string }; - await this.executionDataRepository.insert({ executionId, workflowData, data }); + await this.executionDataRepository.insert({ + executionId, + workflowData, + data, + workflowVersionId: currentWorkflow.versionId, + }); return String(executionId); } else { // All other database drivers should create executions and execution-data atomically @@ -378,7 +383,7 @@ export class ExecutionRepository extends Repository { }); const { id: executionId } = inserted[0] as { id: string }; await this.executionDataRepository.createExecutionDataForExecution( - { executionId, workflowData, data }, + { executionId, workflowData, data, workflowVersionId: currentWorkflow.versionId }, transactionManager, ); return String(executionId);