php Symfony2, Doctrine2 - 强制更新 - 多对多关系中的表已经存在

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19070458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 18:47:14  来源:igfitidea点击:

Symfony2, Doctrine2 - force update - table already exists on many-to-many relation

phpsymfonydoctrine-orm

提问by Lkopo

After I successfuly created TaskBundle with One-to-Many relation between category and tasks, now I'm trying to create a new TaskBundle with Many-to-Many relation. I get also problem with checking checkbox in this relation, but now it is not a primary problem (maybe after solving this). I deleted all tables, which is TaskBundle using and trying to create a new, but here is problem (description at the bottom).

在我成功创建了具有类别和任务之间一对多关系的 TaskBundle 之后,现在我正在尝试创建一个具有多对多关系的新 TaskBundle。在这种关系中检查复选框也有问题,但现在它不是主要问题(也许在解决这个问题之后)。我删除了所有表,这是 TaskBundle 使用并尝试创建一个新表,但这里有问题(底部的描述)。

My Task object:

我的任务对象:

<?php

namespace Acme\TaskBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="tasks") 
 */
class Task
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;              

    /**
     * @ORM\Column(type="string", length=200)    
     * @Assert\NotBlank(
     *      message = "Task is empty"      
     * )    
     * @Assert\Length(
     *      min = "3",
     *      minMessage = "Task is too short"         
     * )     
     */     
    protected $task;

    /**
     * @ORM\Column(type="datetime")    
     * @Assert\NotBlank()
     * @Assert\Type("\DateTime")
     */
    protected $dueDate;

    /**
     * @Assert\True(message = "You have to agree.")    
     */         
    protected $accepted;

    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="tasks")
     * @ORM\JoinTable(name="categories")                         
     */
    protected $category;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->category = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set task
     *
     * @param string $task
     * @return Task
     */
    public function setTask($task)
    {
        $this->task = $task;

        return $this;
    }

    /**
     * Get task
     *
     * @return string 
     */
    public function getTask()
    {
        return $this->task;
    }

    /**
     * Set dueDate
     *
     * @param \DateTime $dueDate
     * @return Task
     */
    public function setDueDate($dueDate)
    {
        $this->dueDate = $dueDate;

        return $this;
    }

    /**
     * Get dueDate
     *
     * @return \DateTime 
     */
    public function getDueDate()
    {
        return $this->dueDate;
    }

    /**
     * Add category
     *
     * @param \Acme\TaskBundle\Entity\Category $category
     * @return Task
     */
    public function addCategory(\Acme\TaskBundle\Entity\Category $category)
    {
        $this->category[] = $category;

        return $this;
    }

    /**
     * Remove category
     *
     * @param \Acme\TaskBundle\Entity\Category $category
     */
    public function removeCategory(\Acme\TaskBundle\Entity\Category $category)
    {
        $this->category->removeElement($category);
    }

    /**
     * Get category
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getCategory()
    {
        return $this->category;
    }
}

and Category object

和类别对象

<?php

namespace Acme\TaskBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="categories") 
 */
class Category
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")             
     */
    protected $id; 

    /**
     * @ORM\Column(type="string", length=200, unique=true)   
     * @Assert\NotNull(message="Categories cannot be empty", groups = {"adding"})                   
     */         
    protected $name;  

    /**
     * @ORM\ManyToMany(targetEntity="Task", mappedBy="category")
     */
    private $tasks;            


    public function __toString()
    {
        return strval($this->name);
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->tasks = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Category
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add tasks
     *
     * @param \Acme\TaskBundle\Entity\Task $tasks
     * @return Category
     */
    public function addTask(\Acme\TaskBundle\Entity\Task $tasks)
    {
        $this->tasks[] = $tasks;

        return $this;
    }

    /**
     * Remove tasks
     *
     * @param \Acme\TaskBundle\Entity\Task $tasks
     */
    public function removeTask(\Acme\TaskBundle\Entity\Task $tasks)
    {
        $this->tasks->removeElement($tasks);
    }

    /**
     * Get tasks
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTasks()
    {
        return $this->tasks;
    }
}

So, after i put doctrine:schema:update --forcei'll get error: Table 'symfony.categories' already exists. I've tried to delete all caches, but same problem. Any idea?

所以,在我放之后,doctrine:schema:update --force我会得到错误:Table 'symfony.categories' already exists。我试图删除所有缓存,但同样的问题。任何的想法?

There's only problem, if it is as m2m relation.

只有问题,如果它是 m2m 关系。

PS: I was looking for this problem at the Google, but no one answers at this problem. There were only questions, but not correct answers, where the problem is and how to solve it.

PS:我在谷歌上寻找这个问题,但没有人回答这个问题。只有问题,但没有正确答案,问题出在哪里以及如何解决。

采纳答案by Igor Pantovi?

Looks like you already have table named "categories" in that database. Remove this line @ORM\JoinTable(name="categories")and try without it.

看起来您在该数据库中已经有名为“类别”的表。删除此行@ORM\JoinTable(name="categories")并尝试不使用它。

P.S. "Categories" is really a strange name for join table. You should probably follow some conventions and let doctrine name it. Common names for join tables are category_taskor category2taskas they are more self-explanatory. Nothing thatimportant, just trying to suggest what I consider good practice.

PS“类别”对于连接表来说真的是一个奇怪的名字。您可能应该遵循一些约定并让学说命名它。连接表的通用名称是category_taskcategory2task因为它们更易于解释。没什么那么重要,只是想建议我认为好的做法。

回答by Ben Tazulev

The thing is that doctrine doesn't understand how your existing table should be used. But you can give him some help.

问题是学说不了解您现有的表格应该如何使用。但是你可以给他一些帮助。

You have two options :

你有两个选择:

  • You don't care about the existing table : simple, you can remove the @ORM\JoinTable(name="categories")annotation, and doctrine will create an other table etc.

  • You want to keep your existing table, which sounds pretty logical : you have to be more explicit in your annotation by adding @ORM\JoinColumnannotation.

  • 您不关心现有表:简单,您可以删除@ORM\JoinTable(name="categories")注释,并且学说将创建另一个表等。

  • 您想保留现有的表,这听起来很合乎逻辑:您必须通过添加@ORM\JoinColumn注释在注释中更加明确。

Here is an example:

下面是一个例子:

class 

<?php
...
/**
 * @ORM\Entity
 * @ORM\Table(name="tasks") 
 */
class Task
{
    ...
    /**
     * @ORM\ManyToMany(targetEntity="Category", inversedBy="tasks")
     * @ORM\JoinTable(name="categories",
     *       joinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")},
     *       inverseJoinColumns={@ORM\JoinColumn(name="task_id", referencedColumnName="id")})                         
     */
    protected $category;
    ...
}

and Category object

和类别对象

<?php
...    
/**
 * @ORM\Entity
 * @ORM\Table(name="categories") 
 */
class Category
{
    ...
    /**
     * @ORM\ManyToMany(targetEntity="Task", mappedBy="category")
     * @ORM\JoinTable(name="categories",
     *       joinColumns={@ORM\JoinColumn(name="task_id", referencedColumnName="id")},
     *       inverseJoinColumns={@ORM\JoinColumn(name="category_id", referencedColumnName="id")})
     */
    private $tasks;            
...

Doing so, you will be able to keep your table without any doctrine error.

这样做,您将能够保持您的桌子而不会出现任何学说错误。

回答by willbradley

My fix for this, as far as I can tell, was a case-sensitivity issue with table names. Doctrine let me create a Usersand a userstable but afterwards would die on migrations:diff or migrations:migrate .

据我所知,我对此的修复是表名区分大小写的问题。Doctrine 让我创建一个Users和一个users表,但之后会死在 migrations:diff 或 migrations:migrate 上。

I used the -vvv option to get more detail on this error message; it seems that the error happens when Doctrine is loading up its own internal representation of the current database's schema. So if your current database has table names that Doctrine doesn't understand (like two tables that are identical, case-insensitive) then it will blow up in this fashion.

我使用 -vvv 选项来获取有关此错误消息的更多详细信息;当 Doctrine 加载它自己的当前数据库模式的内部表示时,错误似乎发生了。因此,如果您当前的数据库具有 Doctrine 无法理解的表名(例如两个相同的、不区分大小写的表),那么它将以这种方式爆炸。

Seems like most of the answers above assume that the error is in your code, but in my case it was in the database.

似乎上面的大多数答案都假设错误在您的代码中,但在我的情况下它在数据库中。

回答by Sakhri Houssem

in Symfony4.1you can force the migration using the migration version

Symfony4.1您可以使用迁移版本强制迁移

doctrine:migrations:execute <migration version>

ex

前任

for migration version123456.phpuse

迁移version123456.php使用

doctrine:migrations:execute 123456

回答by Kaizoku Gambare

I got this error with 2 ManyToMany targeting the same entity (User in the exemple below).

我遇到了针对同一实体的 2 ManyToMany 错误(下面示例中的用户)。

To create the table name doctrine use the entity and target entity name.

要创建表名原则,请使用实体和目标实体名称。

So in my case it was trying to create two time the table thread_user

所以在我的情况下,它试图创建两次表 thread_user

To debug this it's easy. Just use the '@ORM\JoinTable' annotation and specify the table name.

调试这个很容易。只需使用 '@ORM\JoinTable' 注释并指定表名。

Here is a working exemple.

这是一个工作示例。

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\User")
 * @ORM\JoinTable(name="thread_participant")
 */
private $participants;

/**
 * @ORM\ManyToMany(targetEntity="App\Entity\User")
 * @ORM\JoinTable(name="thread_recipient")
 */
private $recipients;

回答by user5164320

there is another using the table name ,you can search it in your project . Maby be demo,I think it... sorry for my chinese english !

还有另一个使用表名,您可以在您的项目中搜索它。Maby 是演示,我认为它......对不起我的中文英语!

回答by zinovyev

Try to drop everything inside of your proxy directory.

尝试删除代理目录中的所有内容。

回答by Jean-Luc Barat

I fix same issue after check other entities on each bundles, be aware of this.

在检查每个包上的其他实体后,我修复了相同的问题,请注意这一点。