Doctrine fixtures 加载,有问题设置引用(外键)违反 -not-null 约束
Doctrine fixtures load, having issue setting references (foreign key) violates -not-null constraint
我正在使用 Doctrine Fixtures 将一些数据加载到我的数据库中,
有 3 个不同的表 User、Theme 和 Sous_Theme,最后两个表有外键,Theme 为 (user.id) 和 Sous_Theme 作为两个外键 (user.id & theme.id)
我的 AppFixtures.php
class 的设置方式是每个模型值都已经以这种方式写入:
private const USERS = [
[
'last_name' => 'Goodman',
'first_name'=> 'Robert',
'email' => 'robert@foobar.com',
'job' => 'Admin_Tester',
'password' => 'blablablablablbal',
'username' => 'blablablabla',
'roles' => [USER::ROLE_ADMIN]
]...
]
private const THEMES =
[
['name' => 'A theme'],
['name' => ' A theme 2']
.....
]
private const SOUSTHEMES = [
[
'name' => 'blablabla',
'part1' => true, //boolean
...
],
在编写 SOUSTHEMES 部分之前,我已经加载了 Users 和 Themes 值以及它完美运行的参考:
public function loadTheme(ObjectManager $manager)
{
foreach (self::THEMES as $themeDate){
$theme = new Theme();
$theme->setName($themeDate['name']);
$date = new \DateTime();
$date->modify('-'. rand(0, 10) . 'day');
$theme->setCreatedAt($date);
//// Setting user Id into our Theme table.
$theme->setUser($this->getReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
$manager->persist($theme);
}
$manager->flush();
}
现在我正在尝试使用引用 theme.id 和 user.id 加载 sousthemes :
public function loadSousThemes(ObjectManager $manager){
foreach (self::SOUSTHEMES as $sousthemeData){
$sousthemes = new SousTheme();
$sousthemes->setName($sousthemeData['name']);
$date = new \DateTime();
$date->modify('-'. rand(0, 10) . 'day');
$sousthemes->setCreatedAt($date);
//// Setting boolean values
$sousthemes->setPart1($sousthemeData['part_n1']);
$sousthemes->setUsername($this->setReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name'], $sousthemes));
$sousthemes->setTheme($this->setReference(
self::THEMES[rand(0, count(self::THEMES) - 1)]['name'], $sousthemes));
$manager->persist($sousthemes);
}
$manager->flush();
我已经开始使用 getReference()
方法,但我发现 ref 不存在,所以我切换到 addReference()
我收到另一个错误,说 ref 已经存在,我需要使用 setReference()
覆盖它所以我将我的方法更改为 setReference()
现在我得到一个错误
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "theme_id" violates not-null constraint
我在 user.id
上也遇到同样的错误。
当我将 user.id 值添加到我的主题时,getReference
完美地工作,但它不适用于 southeme 我试图找出原因,是因为我正在注入两个外键,这是我非常怀疑的事情,我不知道我错过了什么,在有人说出来之前大声笑是的,我正在以正确的顺序加载我的价值观,首先是用户,然后是主题,然后是 sousthemes :
public function load(ObjectManager $manager)
{
$this->loadUsers($manager);
$this->loadTheme($manager);
$this->loadSousThemes($manager);
}
这是 UploadUsers 函数:
public function loadUsers(ObjectManager $manager)
{
foreach (self::USERS as $userData)
{
$user = new User();
$user->setFirstName($userData['first_name']);
$user->setLastName($userData['last_name']);
$user->setEmail($userData['email']);
$user->setJob($userData['job']);
$user->setPassword($this->passwordEncoder->
encodePassword($user, $userData['password']));
$user->setUsername($userData['username']);
$user->setCreatedAt(new \DateTime());
$user->setRoles($userData['roles']);
$this->addReference($userData['last_name'], $user);
$manager->persist($user);
}
$manager->flush();
}
首先你根本不需要addReference/getReference,因为你只使用一个夹具文件。因此,在您的情况下,您可以只保存对象并在设置器中使用它们,例如:
in loadUsers:
public function loadUsers(ObjectManager $manager)
{
foreach (self::USERS as $userData)
{
$user = new User();
///...
$manager->persist($user);
$this->users[$userData['username']] = $user;
}
$manager->flush();
}
and in loadTheme:
$theme->setUser($this->users[self::USERS[rand(0, count(self::USERS) - 1)]['username']]);
您不需要引用,因为您可以访问对象,当夹具位于单独的文件中时,引用很有用,因为这样您就无法访问在不同夹具文件中创建的对象。
此处描述:https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#sharing-objects-between-fixtures .
但是假设您想使用引用,我会尝试提供一些指导来修复您已有的代码。你说通过引用加载用户对主题有用:
$theme->setUser($this->getReference(self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
之所以有效,是因为您在 loadUsers
:
中添加了引用
$this->addReference($userData['last_name'], $user);
所以在 loadUsers
之后,您可以使用这些参考资料:
User objects:
- Goodman
- ...
现在,无论何时调用 $this->getReference('Goodman');
,您都将获得可在 setter 中使用的用户对象,例如。设置用户();
但您从未在 loadTheme
中调用 addReference
来保存对主题对象的引用。
将addReference
添加到loadTheme
:
public function loadTheme(ObjectManager $manager)
{
foreach (self::THEMES as $themeDate){
$theme = new Theme();
$theme->setName($themeDate['name']);
// ...
$theme->setUser($this->getReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
$manager->persist($theme);
$this->addReference($theme->getName(), $theme);
}
$manager->flush();
}
所以在 loadUsers
和 loadThemes
之后,这些参考资料将可用:
User objects:
- Goodman
- ...
Theme objects:
- A theme
- A theme 2
- ...
最后在你的 loadSousThemes
:
$sousthemes->setUsername($this->getReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
$sousthemes->setTheme($this->getReference(
self::THEMES[rand(0, count(self::THEMES) - 1)]['name']));
请注意,我假设 $sousthemes->setUsername()
确实是用于设置用户对象,而不仅仅是用户名(为什么不称为 setUser?)
我正在使用 Doctrine Fixtures 将一些数据加载到我的数据库中, 有 3 个不同的表 User、Theme 和 Sous_Theme,最后两个表有外键,Theme 为 (user.id) 和 Sous_Theme 作为两个外键 (user.id & theme.id)
我的 AppFixtures.php
class 的设置方式是每个模型值都已经以这种方式写入:
private const USERS = [
[
'last_name' => 'Goodman',
'first_name'=> 'Robert',
'email' => 'robert@foobar.com',
'job' => 'Admin_Tester',
'password' => 'blablablablablbal',
'username' => 'blablablabla',
'roles' => [USER::ROLE_ADMIN]
]...
]
private const THEMES =
[
['name' => 'A theme'],
['name' => ' A theme 2']
.....
]
private const SOUSTHEMES = [
[
'name' => 'blablabla',
'part1' => true, //boolean
...
],
在编写 SOUSTHEMES 部分之前,我已经加载了 Users 和 Themes 值以及它完美运行的参考:
public function loadTheme(ObjectManager $manager)
{
foreach (self::THEMES as $themeDate){
$theme = new Theme();
$theme->setName($themeDate['name']);
$date = new \DateTime();
$date->modify('-'. rand(0, 10) . 'day');
$theme->setCreatedAt($date);
//// Setting user Id into our Theme table.
$theme->setUser($this->getReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
$manager->persist($theme);
}
$manager->flush();
}
现在我正在尝试使用引用 theme.id 和 user.id 加载 sousthemes :
public function loadSousThemes(ObjectManager $manager){
foreach (self::SOUSTHEMES as $sousthemeData){
$sousthemes = new SousTheme();
$sousthemes->setName($sousthemeData['name']);
$date = new \DateTime();
$date->modify('-'. rand(0, 10) . 'day');
$sousthemes->setCreatedAt($date);
//// Setting boolean values
$sousthemes->setPart1($sousthemeData['part_n1']);
$sousthemes->setUsername($this->setReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name'], $sousthemes));
$sousthemes->setTheme($this->setReference(
self::THEMES[rand(0, count(self::THEMES) - 1)]['name'], $sousthemes));
$manager->persist($sousthemes);
}
$manager->flush();
我已经开始使用 getReference()
方法,但我发现 ref 不存在,所以我切换到 addReference()
我收到另一个错误,说 ref 已经存在,我需要使用 setReference()
覆盖它所以我将我的方法更改为 setReference()
现在我得到一个错误
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "theme_id" violates not-null constraint
我在 user.id
上也遇到同样的错误。
当我将 user.id 值添加到我的主题时,getReference
完美地工作,但它不适用于 southeme 我试图找出原因,是因为我正在注入两个外键,这是我非常怀疑的事情,我不知道我错过了什么,在有人说出来之前大声笑是的,我正在以正确的顺序加载我的价值观,首先是用户,然后是主题,然后是 sousthemes :
public function load(ObjectManager $manager)
{
$this->loadUsers($manager);
$this->loadTheme($manager);
$this->loadSousThemes($manager);
}
这是 UploadUsers 函数:
public function loadUsers(ObjectManager $manager)
{
foreach (self::USERS as $userData)
{
$user = new User();
$user->setFirstName($userData['first_name']);
$user->setLastName($userData['last_name']);
$user->setEmail($userData['email']);
$user->setJob($userData['job']);
$user->setPassword($this->passwordEncoder->
encodePassword($user, $userData['password']));
$user->setUsername($userData['username']);
$user->setCreatedAt(new \DateTime());
$user->setRoles($userData['roles']);
$this->addReference($userData['last_name'], $user);
$manager->persist($user);
}
$manager->flush();
}
首先你根本不需要addReference/getReference,因为你只使用一个夹具文件。因此,在您的情况下,您可以只保存对象并在设置器中使用它们,例如:
in loadUsers:
public function loadUsers(ObjectManager $manager)
{
foreach (self::USERS as $userData)
{
$user = new User();
///...
$manager->persist($user);
$this->users[$userData['username']] = $user;
}
$manager->flush();
}
and in loadTheme:
$theme->setUser($this->users[self::USERS[rand(0, count(self::USERS) - 1)]['username']]);
您不需要引用,因为您可以访问对象,当夹具位于单独的文件中时,引用很有用,因为这样您就无法访问在不同夹具文件中创建的对象。 此处描述:https://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#sharing-objects-between-fixtures .
但是假设您想使用引用,我会尝试提供一些指导来修复您已有的代码。你说通过引用加载用户对主题有用:
$theme->setUser($this->getReference(self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
之所以有效,是因为您在 loadUsers
:
$this->addReference($userData['last_name'], $user);
所以在 loadUsers
之后,您可以使用这些参考资料:
User objects:
- Goodman
- ...
现在,无论何时调用 $this->getReference('Goodman');
,您都将获得可在 setter 中使用的用户对象,例如。设置用户();
但您从未在 loadTheme
中调用 addReference
来保存对主题对象的引用。
将addReference
添加到loadTheme
:
public function loadTheme(ObjectManager $manager)
{
foreach (self::THEMES as $themeDate){
$theme = new Theme();
$theme->setName($themeDate['name']);
// ...
$theme->setUser($this->getReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
$manager->persist($theme);
$this->addReference($theme->getName(), $theme);
}
$manager->flush();
}
所以在 loadUsers
和 loadThemes
之后,这些参考资料将可用:
User objects:
- Goodman
- ...
Theme objects:
- A theme
- A theme 2
- ...
最后在你的 loadSousThemes
:
$sousthemes->setUsername($this->getReference(
self::USERS[rand(0, count(self::USERS) - 1)]['last_name']));
$sousthemes->setTheme($this->getReference(
self::THEMES[rand(0, count(self::THEMES) - 1)]['name']));
请注意,我假设 $sousthemes->setUsername()
确实是用于设置用户对象,而不仅仅是用户名(为什么不称为 setUser?)