Php 不将重复项插入MySQL DB-条令和Symfony2

Php 不将重复项插入MySQL DB-条令和Symfony2,php,mysql,symfony,doctrine-orm,doctrine,Php,Mysql,Symfony,Doctrine Orm,Doctrine,我使用Symfony2和Doctrine将API中的一些数据持久化到MySQL数据库中。我有一个名为Gig的实体,我使用注释来设置约束。我认为这其中的相关部分如下所示: namespace London\HelloBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; /** * Gig * @ORM\Table(uniq

我使用Symfony2和Doctrine将API中的一些数据持久化到MySQL数据库中。我有一个名为Gig的实体,我使用注释来设置约束。我认为这其中的相关部分如下所示:

namespace London\HelloBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * Gig
 * @ORM\Table(uniqueConstraints={@ORM\UniqueConstraint(columns={"Artist", "ConcertDate"})})
 * @ORM\Entity
 */
class Gig
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 * @ORM\Column(name="Artist", type="string", length=255, nullable=true)
 */
private $artist;

/**
 * @var string
 * @ORM\Column(name="ConcertDate", type="string", length=255)
 */
private $concertDate;
在我的控制器中,我使用Buzz遍历API并将我想要的位持久化到DB中。对于第一次导入,这一切都很好

但是,我已经将Artist和ConcertDate列的组合设置为唯一,因为我不想将相同的项目从API读取到数据库中两次。当我触发处理这个问题的操作时,我得到了错误

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'Plaid-2014-08-12' for key      'UNIQ_ED7D66426F593B176DAA24E'
500 Internal Server Error - DBALException
1 linked Exception: PDOException »
我认为这是应该的,但我真正想要的是保留新数据并跳过我已经拥有的数据。有人能帮我吗

编辑: 添加根据注释请求将数据持久化到db的代码

namespace London\APIBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use London\HelloBundle\Entity\Gig;

class DefaultController extends Controller
{
  public function indexAction()
  {
    $buzz = $this->container->get('buzz');
    $response = $buzz->get('http://myapiuri');
    echo $buzz->getLastRequest(). "\n";
    $content = $response->getContent();
    $data = json_decode($content);
    $stuff=$data->resultsPage->results->event;
    for ($i=0; $i < sizeof($stuff) ; $i++) {
        $gig = new Gig();
        if(isset($stuff[$i]->performance[0])){
            $gig->setArtist($stuff[$i]->performance[0]->displayName);
        }
        $gig->setConcertDate($stuff[$i]->start->date);
        $gig->setVenueName($stuff[$i]->venue->displayName);
        $gig->setGenre($stuff[$i]->type);
        $gig->setVenueAddress('45 Queen Caroline Street, London, England W6 9QH');

        $em = $this->getDoctrine()->getManager();
        $em->persist($gig);
        $em->flush();   

    }
    return $this->render('LondonAPIBundle:Default:index.html.twig');
  }
}
namespace-London\APIBundle\Controller;
使用Symfony\Bundle\FrameworkBundle\Controller\Controller;
使用London\HelloBundle\Entity\Gig;
类DefaultController扩展控制器
{
公共函数索引()
{
$buzz=$this->container->get('buzz');
$response=$buzz->get($response)http://myapiuri');
echo$buzz->getLastRequest()。“\n”;
$content=$response->getContent();
$data=json_decode($content);
$stuff=$data->resultsPage->results->event;
对于($i=0;$i性能[0])){
$gig->setArtist($stuff[$i]->performance[0]->displayName);
}
$gig->setConcertDate($stuff[$i]->开始->日期);
$gig->setVenueName($stuff[$i]->vention->displayName);
$gig->setGenre($stuff[$i]->type);
$gig->setVenueAddress(英国伦敦卡罗琳皇后街45号,W6 9QH);
$em=$this->getDoctrine()->getManager();
$em->persist($gig);
$em->flush();
}
返回$this->render('LondonAPIBundle:Default:index.html.twig');
}
}

删除唯一约束

uniqueConstraints={@ORM\UniqueConstraint(columns={"Artist", "ConcertDate"})}

如果有可能在同一日期举行两场音乐会,请选择同一艺术家。

您可以检查是否已经存在具有相同密钥的实体,如果不存在,则仅插入

$exists = $em->getRepository('London\HelloBundle\Entity\Gig')->findBy(array(
    'Artist' => $gig->getArtist(), 
    'ConcertDate' => $gig->getConcertDate()
);

if(!$exists) {
    $em->persist($gig);
    $em->flush();
}
或者,您可以捕获重复的异常

try {
    $em->persist($gig);
    $em->flush(); 
}
catch(\Doctrine\DBAL\DBALException $e) {

    //if the error is not for duplicates, throw the error
    if($e->getErrorCode() != $error_code_for_dupes) {
        throw $e;
    }

    //otherwise ignore it
}

谢谢你,德米特里。我想保留这个限制(或者类似的限制——可能还包括场地)。我真正想要的是如何让Doctrine/Symfony在API中传递已经存在于db中的数据,并且只保留尚未存在于db中的数据。你能分享将实体保留到db的代码吗?谢谢@FuzzyTree我编辑了这篇文章来展示这段代码。谢谢@FuzzyTree。我一两天内都不会尝试这个。我想说声谢谢,让你知道我并没有忽视你的帮助:)我把这个标记为答案,因为你的第一个解决方案确实解决了这个问题。第二个选项不起作用-首先,$e->getErrorCode出现问题(切换到$e->getCode是可以的),但是如果($e->getCode()!=1062)似乎不起作用,则允许继续插入。再次感谢你!