[REQUIRED_FOR_1_10] Fix kanban foreign key migration (#15557)
# Introduction We introduced a foreign key addition that will fail in production due to orphan views targetting non existing fields ## Migration The migration will be run for any new workspace successfully or any twenty instance without corrupted data ## Upgrade command The upgrade command will at some point allow the migration to be run manually after removing any corrupted data ## Release note We should remove the migration we've manually set as being run in production
This commit is contained in:
+57
@@ -0,0 +1,57 @@
|
||||
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Command } from 'nest-commander';
|
||||
import { DataSource, Repository } from 'typeorm';
|
||||
|
||||
import {
|
||||
ActiveOrSuspendedWorkspacesMigrationCommandRunner,
|
||||
type RunOnWorkspaceArgs,
|
||||
} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager';
|
||||
|
||||
@Command({
|
||||
name: '1-10-create-view-kanban-field-metadata-id-foreign-key-migration',
|
||||
description:
|
||||
'Create FK_b3cc95732479f7a1337350c398f foreign key on view kanban field metadata id column',
|
||||
})
|
||||
export class CreateViewKanbanFieldMetadataIdForeignKeyMigrationCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner {
|
||||
private hasRunOnce = false;
|
||||
|
||||
constructor(
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
protected readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
protected readonly twentyORMGlobalManager: TwentyORMGlobalManager,
|
||||
@InjectDataSource()
|
||||
private readonly coreDataSource: DataSource,
|
||||
) {
|
||||
super(workspaceRepository, twentyORMGlobalManager);
|
||||
}
|
||||
|
||||
override async runOnWorkspace({
|
||||
options,
|
||||
}: RunOnWorkspaceArgs): Promise<void> {
|
||||
if (this.hasRunOnce) {
|
||||
this.logger.log('Skipping kanban field metadata id foreign key creation');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!options.dryRun) {
|
||||
try {
|
||||
await this.coreDataSource.query(
|
||||
`ALTER TABLE "core"."view" ADD CONSTRAINT "FK_b3cc95732479f7a1337350c398f" FOREIGN KEY ("kanbanAggregateOperationFieldMetadataId") REFERENCES "core"."fieldMetadata"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
this.logger.log(
|
||||
'Successfully added foreign key constraint for kanbanAggregateOperationFieldMetadataId',
|
||||
);
|
||||
} catch (error) {
|
||||
this.logger.log(
|
||||
`Foreign key constraint already exists or could not be created (this is expected for subsequent workspaces): ${error.message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.hasRunOnce = true;
|
||||
}
|
||||
}
|
||||
+3
@@ -3,6 +3,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { AddWorkflowRunStopStatusesCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-add-workflow-run-stop-statuses.command';
|
||||
import { CleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-clean-orphaned-kanban-aggregate-operation-field-metadata-id.command';
|
||||
import { CreateViewKanbanFieldMetadataIdForeignKeyMigrationCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-create-view-kanban-field-metadata-id-foreign-key-migration.command';
|
||||
import { MigrateAttachmentAuthorToCreatedByCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-migrate-attachment-author-to-created-by.command';
|
||||
import { MigrateAttachmentTypeToFileCategoryCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-migrate-attachment-type-to-file-category.command';
|
||||
import { MigrateChannelPartialFullSyncStagesCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-migrate-channel-partial-full-sync-stages.command';
|
||||
@@ -32,6 +33,7 @@ import { WorkspaceSchemaManagerModule } from 'src/engine/twenty-orm/workspace-sc
|
||||
RegenerateSearchVectorsCommand,
|
||||
AddWorkflowRunStopStatusesCommand,
|
||||
CleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand,
|
||||
CreateViewKanbanFieldMetadataIdForeignKeyMigrationCommand,
|
||||
],
|
||||
exports: [
|
||||
MigrateAttachmentAuthorToCreatedByCommand,
|
||||
@@ -40,6 +42,7 @@ import { WorkspaceSchemaManagerModule } from 'src/engine/twenty-orm/workspace-sc
|
||||
AddWorkflowRunStopStatusesCommand,
|
||||
CleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand,
|
||||
MigrateChannelPartialFullSyncStagesCommand,
|
||||
CreateViewKanbanFieldMetadataIdForeignKeyMigrationCommand,
|
||||
],
|
||||
})
|
||||
export class V1_10_UpgradeVersionCommandModule {}
|
||||
|
||||
+3
@@ -11,6 +11,7 @@ import {
|
||||
} from 'src/database/commands/command-runners/upgrade.command-runner';
|
||||
import { AddWorkflowRunStopStatusesCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-add-workflow-run-stop-statuses.command';
|
||||
import { CleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-clean-orphaned-kanban-aggregate-operation-field-metadata-id.command';
|
||||
import { CreateViewKanbanFieldMetadataIdForeignKeyMigrationCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-create-view-kanban-field-metadata-id-foreign-key-migration.command';
|
||||
import { MigrateAttachmentAuthorToCreatedByCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-migrate-attachment-author-to-created-by.command';
|
||||
import { MigrateAttachmentTypeToFileCategoryCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-migrate-attachment-type-to-file-category.command';
|
||||
import { MigrateChannelPartialFullSyncStagesCommand } from 'src/database/commands/upgrade-version-command/1-10/1-10-migrate-channel-partial-full-sync-stages.command';
|
||||
@@ -61,6 +62,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
||||
protected readonly addWorkflowRunStopStatusesCommand: AddWorkflowRunStopStatusesCommand,
|
||||
protected readonly cleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand: CleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand,
|
||||
protected readonly migrateChannelPartialFullSyncStagesCommand: MigrateChannelPartialFullSyncStagesCommand,
|
||||
protected readonly createViewKanbanFieldMetadataIdForeignKeyMigrationCommand: CreateViewKanbanFieldMetadataIdForeignKeyMigrationCommand,
|
||||
) {
|
||||
super(
|
||||
workspaceRepository,
|
||||
@@ -97,6 +99,7 @@ export class UpgradeCommand extends UpgradeCommandRunner {
|
||||
this.regenerateSearchVectorsCommand,
|
||||
this.addWorkflowRunStopStatusesCommand,
|
||||
this.cleanOrphanedKanbanAggregateOperationFieldMetadataIdCommand,
|
||||
this.createViewKanbanFieldMetadataIdForeignKeyMigrationCommand,
|
||||
this.migrateChannelPartialFullSyncStagesCommand,
|
||||
],
|
||||
afterSyncMetadata: [
|
||||
|
||||
+12
-3
@@ -6,9 +6,18 @@ export class KanbanFieldMetadataIdentifierView1760965667836
|
||||
name = 'KanbanFieldMetadataIdentifierView1760965667836';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."view" ADD CONSTRAINT "FK_b3cc95732479f7a1337350c398f" FOREIGN KEY ("kanbanAggregateOperationFieldMetadataId") REFERENCES "core"."fieldMetadata"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
// Swallowing any exceptions here
|
||||
// 1-10-clean-orphaned-kanban-aggregate-operation-field-metadata-id.command.ts upgrade command handles fallback for existing workspaces
|
||||
try {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "core"."view" ADD CONSTRAINT "FK_b3cc95732479f7a1337350c398f" FOREIGN KEY ("kanbanAggregateOperationFieldMetadataId") REFERENCES "core"."fieldMetadata"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
||||
);
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(
|
||||
`Swallowing KanbanFieldMetadataIdentifierView1760965667836 error: ${error.message}. Upgrade:1-10:clean-orphaned-kanban-aggregate-operation-field-metadata-id upgrade command will handle fallback`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user