Php 不将重复项插入MySQL DB-条令和Symfony2
我使用Symfony2和Doctrine将API中的一些数据持久化到MySQL数据库中。我有一个名为Gig的实体,我使用注释来设置约束。我认为这其中的相关部分如下所示: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
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)似乎不起作用,则允许继续插入。再次感谢你!