执行迁移失败主因是数据库连接配置错误或迁移文件未被识别。需检查.env中database_url、doctrine配置、docker网络设置;迁移类必须用addsql()而非原生sql;迁移文件名和路径须严格匹配versionyyyymmddhhiiss格式且位于src/migrations下。

直接执行 php bin/console doctrine:migrations:migrate 就能跑完迁移,但多数失败不是命令错,而是环境或配置没对齐。
迁移命令本身不报错,但数据库没变
常见现象:控制台显示 Successfully migrated,但表结构、数据都没更新。根本原因是 Doctrine 没连上你认为的那个数据库。
- 检查
.env中的DATABASE_URL是否指向目标库(比如本地开发用sqlite:///%kernel.project_dir%/var/data.db,但你实际改了 MySQL 配置却忘了改这里) - 运行
php bin/console debug:config doctrine,确认输出里connections.default.url和你预期一致,且driver是pdo_mysql或pdo_sqlite而非pdo_pgsql - 如果用了 Docker,确认容器内
DATABASE_URL的 host 是db(不是localhost),端口是容器暴露的 3306,不是宿主机的 3307
Migration 类里写了 SQL,但执行后字段没加
Symfony 5.3 默认用 Doctrine Migrations v3,它依赖 doctrine/migrations 包,而该版本不再自动解析 up() 方法里的原生 SQL —— 它只认 $this->addSql() 显式调用。
- 错误写法:
public function up(Schema $schema): void { $conn = $this->connection; $conn->executeStatement('ALTER TABLE user ADD COLUMN avatar VARCHAR(255)'); } - 正确写法:
public function up(Schema $schema): void { $this->addSql('ALTER TABLE user ADD COLUMN avatar VARCHAR(255)'); } - 别在
up()里用$schema->createTable()等 Schema API 操作,除非你明确禁用了 SQL 生成(--no-dump-sql),否则会和addSql()冲突
执行 migrate 提示 “No migrations to execute”
不是没写迁移文件,而是 Doctrine 认为这些迁移已“执行过”——它的判断依据是 doctrine_migrations 表(MySQL)或 doctrine_migration_versions 表(SQLite)里的记录。
- 先查表:
SELECT * FROM doctrine_migrations;(MySQL)或SELECT * FROM doctrine_migration_versions;(SQLite) - 如果看到你的迁移版本号已存在,但实际没生效,说明上次执行中途失败或被中断;手动删掉对应行再重试
- 如果刚初始化项目,但
doctrine:migrations:status显示10 migrations have no execution status,运行php bin/console doctrine:migrations:sync-metadata-storage初始化元数据表 - 别用
doctrine:migrations:force强制标记为已执行——它跳过 SQL 执行,只改状态,极易导致结构和元数据不一致
最常被忽略的点:迁移类名必须严格匹配版本号格式,比如 Version20240515120000,且文件名必须是 src/Migrations/Version20240515120000.php。少一个零、大小写错、路径不在 src/Migrations 下,Doctrine 就直接无视这个文件。











