symfony7之DataFixtures使用注意事项:
1>一般直接执行 php bin/console doctrine:fixtures:load --append 即可将数据初始化到数据库。一定要加 --append, 除非是第一次拉项目,初始化数据库, 否则操作会清空整个数据库(purging database)中的所有表,而不是仅仅清空与指定 group 相关的表. 这直接会把已经存在的数据清理掉.
2>假如后来在DataFixtures又有了新的fixture的话,我只想执行新添加的怎么办 ①一开始想到的是如下方法 php bin/console doctrine:fixtures:load --fixtures=src/DataFixtures/LoadEventSubmissionFileRequiredOptionsData.php --fixtures=src/DataFixtures/LoadEventSubmissionFiletypesData.php --fixtures=src/DataFixtures/LoadEventSubmissionTypeWorkflowsData.php --fixtures=src/DataFixtures/LoadEventSubmissionWorkflowData.php
但是报: doctrine:fixtures:load [--append] [--group GROUP] [--em EM] [--purger PURGER] [--purge-exclusions PURGE-EXCLUSIONS] [--purge-with-truncate] 也即是没有 --fixtures 选项(说明这个方法是错的,没用)
②使用 group 解决这个问题(真的很实用)
定义组标签: 首先,
DataFixture类中实现FixtureGroupInterface,并定义一个组标签。例如:<?php namespace App\DataFixtures; use Doctrine\Bundle\FixturesBundle\Fixture; use Doctrine\Persistence\ObjectManager; use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface; // 必须要实现这个FixtureGroupInterface class UserFixtures extends Fixture implements FixtureGroupInterface { public function load(ObjectManager $manager): void { // 定义数据加载逻辑 } public static function getGroups(): array { return ['userGroup']; } }加载特定的组: 在执行命令时,可以通过
--group参数指定要加载的Fixtures组:php bin/console doctrine:fixtures:load --group=userGroup如果想同时加载多个组,可以添加多个
--group参数:php bin/console doctrine:fixtures:load --group=userGroup --group=productGroup
3>小插曲 当时忘了加 --append, 然后无法直接取消,然后直接关了 terminal, 但是后台的进程肯定还在运行,再次执行加上了 --append, 直接报了下面的错误 An exception occurred while executing a query: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction
原因分析: 因为你在第一次执行 doctrine:fixtures:load 时没有使用 --append,导致数据库在执行清空操作时被锁定,而你中断了这个进程(关闭了 terminal 对话框)。这会导致事务没有正确结束,造成表被锁定,从而引发了后续的锁等待超时问题 (Lock wait timeout exceeded)。
处理步骤
1. 检查并终止锁定的事务
你可以通过 MySQL 命令来查看和终止未完成的事务:
查看当前的锁定情况: 使用以下命令查看当前被锁定的事务:
SHOW ENGINE INNODB STATUS;这个命令会返回详细的 InnoDB 状态信息,帮助你找出哪个事务占用了锁。
终止锁定的事务: 使用
SHOW FULL PROCESSLIST查找长时间运行的查询,然后使用KILL QUERY终止它。SHOW FULL PROCESSLIST;查找到
state为Locked的查询,记下对应的ID,然后使用以下命令终止该查询:KILL QUERY <ID>;
2. 重启 MySQL 服务(如有必要)
如果手动终止事务没有效果,或者你不确定哪个事务在持有锁,重启 MySQL 服务会释放所有锁定的事务:
sudo systemctl restart mysql
3. 再次执行 doctrine:fixtures:load 并使用 --append
清除锁定问题后,再次执行 doctrine:fixtures:load,并确保这次使用 --append,以防止数据被清空:
php bin/console doctrine:fixtures:load --group=event_submission --append
这样可以避免再次清空整个数据库,保留已有数据,同时加载指定的 Fixtures。
总结
- 未正确结束的事务可能会造成数据库锁定,导致后续操作失败。
- 检查并终止锁定的事务,或者通过重启 MySQL 服务释放锁。
- 重新运行
doctrine:fixtures:load时使用--append,以避免再次触发purging database操作。
