在创建迁移时,Doctrine多对多关系想要创建一个表两次

时间:2022-10-05 12:12:17

Before I describe my problem, it might actually make it clearer if I start with the error I'm getting:

在我描述我的问题之前,如果我从我得到的错误开始,它实际上可能会更清楚:

$ ./app/console doc:mig:diff

  [Doctrine\DBAL\Schema\SchemaException]                 
  The table with name 'user_media_area' already exists.  

That's absolutely true - user_media_area does exist. I created it in a previous migration and I don't understand why Symfony is trying to create the table again.

这绝对是真的 - user_media_area确实存在。我在之前的迁移中创建了它,我不明白为什么Symfony会再次尝试创建表。

My problem has something to do with a many-to-many relationship. I have a table called user, a table called media_area and a table called user_media_area.

我的问题与多对多关系有关。我有一个名为user的表,一个名为media_area的表和一个名为user_media_area的表。

Here's the code where I tell user about media_area (Entity/User.php):

这是我告诉用户media_area(Entity / User.php)的代码:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 * @JoinTable(name="user_media_area",
 *      joinColumns={@JoinColumn(name="user_id", referencedColumnName="id")},
 *      inverseJoinColumns={@JoinColumn(name="media_area_id", referencedColumnName="id")}
 *      )
 */
private $mediaAreas;

And here's where I tell media_area about user (Entity/MediaArea.php):

这是我告诉media_area关于用户(Entity / MediaArea.php)的地方:

/** 
 * @ORM\ManyToMany(targetEntity="User", mappedBy="users")
 */
private $users;

What's interesting is that if I remove that JoinTable stuff from Entity/User.php, ./app/console doctrine:migrations:diff will work again:

有趣的是,如果我从Entity / User.php中移除JoinTable的东西,。/ app / console doctrine:migrations:diff将再次起作用:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 */
private $mediaAreas;

However, it's a little off: it now wants to create a new table called mediaarea, which I don't want. My table already exists and it's called media_area.

然而,它有点偏离:它现在想要创建一个名为mediaarea的新表,我不想要它。我的表已经存在,它叫做media_area。

So it looks like either way, Symfony is trying to create a table based on this ManyToMany thing in my User class, and the only reason the problem goes away when I remove the JoinTable is that the name of the table it wants to create (mediaarea) no longer matches the actual name of my table (media_area).

所以它看起来像两种方式,Symfony试图在我的User类中基于这个ManyToMany创建一个表,并且当我删除JoinTable时问题消失的唯一原因是它想要创建的表的名称(mediaarea) )不再匹配我的表的实际名称(media_area)。

So my question is: Why does it want to create a new table at all? What am I doing wrong?

所以我的问题是:为什么要创建一个新表呢?我究竟做错了什么?

(I know it's possible that my naming conventions are off. Symfony and Doctrine's database examples are frustratingly devoid of multi-term column names, so I don't always know if I'm supposed to do media_area or mediaArea.)

(我知道我的命名约定可能已经关闭.Symfony和Doctrine的数据库示例令人沮丧地缺乏多项列名,所以我不知道我是否应该做media_area或mediaArea。)

1 个解决方案

#1


4  

According to the Association Mapping explanation on the official docs, the @JoinColumn and @JoinTable definitions are usually optional and have sensible default values, being:

根据关于官方文档的Association Mapping说明,@ JoinColumn和@JoinTable定义通常是可选的,并且具有合理的默认值,如下:

name: "<fieldname>_id"
referencedColumnName: "id"

From that we can conclude that there is really no concrete difference between the two implementations you presented.

由此我们可以得出结论,您提出的两个实现之间确实没有具体的区别。

However, when it comes to migration, the creation of the table is a pretty common and expected behaviour. The thing is the table should always get deleted and created again, which is not happenning.

但是,在迁移时,表的创建是一种非常常见且预期的行为。事情是表应该总是被删除并再次创建,这不会发生。

About the table name issue, the default behaviour of Doctrine 2 about this:

关于表名问题,Doctrine 2的默认行为是关于此:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 */
private $mediaAreas;

Is to try and create a table called mediaarea. Again, perfectly normal.

是尝试创建一个名为mediaarea的表。再次,完全正常。

If you want to declare a specific name for the table of an entity, you should do this:

如果要为实体表声明特定名称,则应执行以下操作:

/**
 * @ORM\Table(name="my_table")
 */
class Something

I'm not sure if that helps you at all, but I guess it puts you, at least, on the right track.

我不确定这对你有什么帮助,但我想它至少会让你走上正轨。

#1


4  

According to the Association Mapping explanation on the official docs, the @JoinColumn and @JoinTable definitions are usually optional and have sensible default values, being:

根据关于官方文档的Association Mapping说明,@ JoinColumn和@JoinTable定义通常是可选的,并且具有合理的默认值,如下:

name: "<fieldname>_id"
referencedColumnName: "id"

From that we can conclude that there is really no concrete difference between the two implementations you presented.

由此我们可以得出结论,您提出的两个实现之间确实没有具体的区别。

However, when it comes to migration, the creation of the table is a pretty common and expected behaviour. The thing is the table should always get deleted and created again, which is not happenning.

但是,在迁移时,表的创建是一种非常常见且预期的行为。事情是表应该总是被删除并再次创建,这不会发生。

About the table name issue, the default behaviour of Doctrine 2 about this:

关于表名问题,Doctrine 2的默认行为是关于此:

/**
 * @ORM\ManyToMany(targetEntity="MediaArea", inversedBy="mediaAreas")
 */
private $mediaAreas;

Is to try and create a table called mediaarea. Again, perfectly normal.

是尝试创建一个名为mediaarea的表。再次,完全正常。

If you want to declare a specific name for the table of an entity, you should do this:

如果要为实体表声明特定名称,则应执行以下操作:

/**
 * @ORM\Table(name="my_table")
 */
class Something

I'm not sure if that helps you at all, but I guess it puts you, at least, on the right track.

我不确定这对你有什么帮助,但我想它至少会让你走上正轨。