核心问题是doctrine未连接目标数据库,需依次检查:.env中database_url配置是否正确、doctrine_migration_versions表状态是否一致、迁移文件是否使用$this->addsql()而非原生sql、实体类是否被doctrine正确识别。

执行成功但表没更新,核心问题不是命令没跑,而是 Doctrine 没连上你“以为”的那个数据库——它确实执行了迁移逻辑,但作用对象错了。
第一步:确认 DATABASE_URL 连的是哪个库
控制台显示 Successfully migrated,只代表迁移类的 up() 方法被调用了,并不保证改的是目标库。最常见错误是:
-
.env 中 DATABASE_URL 还是默认的 SQLite 路径(如
sqlite:///%kernel.project_dir%/var/data.db),而你实际想操作的是 MySQL; -
Docker 环境下 host 写成了 localhost,应改为服务名(如
db); - 密码含 @ / : 未 URL 编码,导致连接串被截断,连到一个不存在或权限不足的实例。
运行 php bin/console debug:config doctrine,重点看输出里 connections.default.url 的值是否和你预期完全一致,包括协议、host、端口、数据库名、用户名。
第二步:检查迁移是否真被记录在状态表里
Doctrine 用 doctrine_migration_versions(SQLite)或 doctrine_migrations(MySQL)表记录已执行版本。如果该表里已有你的迁移版本号,但表结构没变,说明上次执行可能中途失败或被中断,状态写入了,SQL 却没执行完。
- 查表:
SELECT * FROM doctrine_migration_versions;(SQLite)或SELECT * FROM doctrine_migrations;(MySQL); - 如果看到你的版本号(如
20240515123456)已存在,但字段没加,手动删掉这一行,再重跑doctrine:migrations:migrate; - 若表为空或根本不存在,先运行
php bin/console doctrine:migrations:sync-metadata-storage初始化元数据表。
第三步:验证迁移文件里写的到底是什么
Symfony 4 默认用 Doctrine Migrations v2.x,它只认 $this->addSql(),不解析原生 SQL 执行语句。
- 错误写法(不会生效):
$conn = $this->connection; $conn->executeStatement('ALTER TABLE user ADD avatar VARCHAR(255)'); - 正确写法:
$this->addSql('ALTER TABLE user ADD avatar VARCHAR(255)'); - 打开迁移文件,确认
up()方法里有$this->addSql()调用,且 SQL 语句非空、语法正确; - 避免混用 Schema API(如
$schema->createTable())和addSql(),二者冲突会导致部分操作被跳过。
第四步:确认实体是否被 Doctrine 正确识别
如果迁移文件是用 doctrine:migrations:diff 生成的,但 diff 结果为空或生成了空文件,那很可能 Doctrine 根本没“看见”你的实体。
- 运行
php bin/console doctrine:mapping:info,检查输出中是否列出你的实体类; - 确认实体类顶部有
@ORM\Entity注解(Symfony 4 主流用 PHP 7.4,非属性语法); - 检查
config/packages/doctrine.yaml中mappings配置是否覆盖了src/Entity/目录; - 命名空间与文件路径必须严格匹配,比如
App\Entity\User必须放在src/Entity/User.php。











