删除文章时遇到外键约束错误:
删除文章失败: Cannot delete or update a parent row: a foreign key constraint fails (`blog`.`article_tags`, CONSTRAINT `FK_f8c9234a4c4cb37806387f0c9e9` FOREIGN KEY (`article_id`) REFERENCES `article` (`id`))
pnpm add -D typeorm @types/node ts-node typescript dotenv @types/dotenv @nestjs/config @nestjs/typeorm mysql2
// src/config/typeorm.config.ts:
import { DataSource } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { config } from 'dotenv';
config();
const configService = new ConfigService();
export default new DataSource({
type: 'mysql',
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT, 10) || 3306,
username: process.env.DB_USERNAME || 'root',
password: process.env.DB_PASSWORD || '123456',
database: process.env.DB_NAME || 'blog',
entities: ['src/modules/**/*.entity{.ts,.js}'],
migrations: ['src/migrations/*{.ts,.js}'],
synchronize: false,
logging: process.env.DB_LOGGING || ['error'],
poolSize: parseInt(process.env.DB_POOL_SIZE, 10) || 10,
connectorPackage: 'mysql2',
extra: {
authPlugin: 'sha256_password',
}
});
在 package.json 中添加:
{
"scripts": {
"typeorm": "typeorm-ts-node-commonjs",
"migration:generate": "npm run typeorm -- migration:generate -d src/config/typeorm.config.ts",
"migration:run": "npm run typeorm -- migration:run -d src/config/typeorm.config.ts",
"migration:revert": "npm run typeorm -- migration:revert -d src/config/typeorm.config.ts"
}
}
pnpm run migration:generate src/migrations/UpdateArticleTagsCascade
就会创建这样的文件: src/migrations/1698345600000-UpdateArticleTagsCascade.ts:
// src/migrations/1698345600000-UpdateArticleTagsCascade.ts:
import { MigrationInterface, QueryRunner } from "typeorm";
export class UpdateArticleTagsCascade1698345600000 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
// 先删除旧的外键约束
await queryRunner.query(`
ALTER TABLE article_tags
DROP FOREIGN KEY FK_f8c9234a4c4cb37806387f0c9e9;
`);
// 添加新的级联删除外键约束
await queryRunner.query(`
ALTER TABLE article_tags
ADD CONSTRAINT FK_f8c9234a4c4cb37806387f0c9e9
FOREIGN KEY (article_id)
REFERENCES article(id)
ON DELETE CASCADE;
`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
// 回滚:删除带CASCADE的外键
await queryRunner.query(`
ALTER TABLE article_tags
DROP FOREIGN KEY FK_f8c9234a4c4cb37806387f0c9e9;
`);
// 添加回原来的外键约束(不带CASCADE)
await queryRunner.query(`
ALTER TABLE article_tags
ADD CONSTRAINT FK_f8c9234a4c4cb37806387f0c9e9
FOREIGN KEY (article_id)
REFERENCES article(id);
`);
}
}
@Entity('article_tags')
export class ArticleTag {
@ManyToOne(() => Article, article => article.articleTags, {
onDelete: 'CASCADE'
})
@JoinColumn({ name: 'article_id' })
article: Article;
// ...其他代码
}
@Entity()
export class Article {
@OneToMany(() => ArticleTag, articleTag => articleTag.article, {
cascade: true,
onDelete: 'CASCADE'
})
articleTags: ArticleTag[];
// ...其他代码
}
# 执行迁移
pnpm run migration:run
# 如需回滚
pnpm run migration:revert
1.检查数据库外键约束:
SHOW CREATE TABLE article_tags;