我在其中一个模型上有关系:

/**

* @ORM\ManyToOne(targetEntity="Page", cascade="persist")

* @ORM\JoinColumn(name="page_id", referencedColumnName="id")

*/

private $parentPage;

当我删除父页面时,出现此错误:

Integrity constraint violation: 1451 Cannot delete or update a parent row: a foreign key constraint fails

基本上,我的模型是页面和页面修订。 删除页面时,我不想删除修订。 我还想在页面修订版本中保留page_id(即,不要将其设置为null)。

我该如何使用Doctrine?

抱歉,我的投票有误,我误解了你的问题。您需要做的是删除实际的外键约束。如果约束是通过Doctrine创建的,则您希望将其配置为不再执行此操作,或者只需要继续删除它即可

@Phil Doctine虽然正在生成模式,但我不知道如何告诉它不添加约束。

另一种选择是添加一个属性(例如enabled),该属性将从搜索中排除该页面。这样做会产生删除页面的效果,而不会违反外键约束。

我环顾四周,也找不到任何实质性的东西。您可以尝试运行创建后脚本来删除约束。也许您可以更改为不支持外键的MyISAM表。

@Phil我认为即使如此,从学说的角度来看,数据不一致可能还会有其他问题。我建议实现页面的软删除(在这种情况下是我的最爱)或将page_id列复制为"备份",然后在删除页面时在page_id上设置null。

@dragoste似乎OP实际上希望数据不一致。我认为上述geoBs软删除评论也是最好的解决方案

软删除可能是最正确的解决方案,但是更改应用程序的所有其他部分以过滤出删除的实体会很费时间。切换到MyISAM也可以,这是我所做的,但是并不理想。

@Petah如果您使用gedmo实现软删除,则无需更改任何内容即可过滤出删除的实体,只需将过滤器作为默认添加到配置文件doctrine: orm: entity_managers: default: filters: softdeleteable: [class: Gedmo\SoftDeleteable\Filter\SoftDeleteableFilter & enabled: true]中即可。然后,只要您想获取已删除的实体,就暂时禁用过滤器$filters = ...->get(doctrine)->getEntityManager()->getFilters(); $filters->disable(softdeleteable); query then enable

根据定义,您不能在不将外键设置为null(onDelete="SET NULL")或级联删除操作的情况下删除外键指向的记录(有两个选项-ORM级别:cascade={"remove"} |数据库级别:onDelete="CASCADE") 。可以为仍然存在的记录设置默认值,但是您必须手动执行此操作,我不认为Doctrine支持此out-of-the-box(如果我输入错误,请更正我,但在这种情况下,请设置默认值)值也不是必需的)。

这种严格性反映了具有外键约束的概念。就像@Théo说的那样:

a FK is to ensure data consistency.

软删除(已经提到)是一种解决方案,但是您也可以做的是添加一个附加的removed_page_id列,该列与page_id同步,然后在preRemove事件处理程序(生命周期回调)中将其删除。这些信息是否具有任何价值,我想知道,但是我想您对此有一定用处,否则您不会问这个问题。

我绝对不是在说这是一种好习惯,但是至少可以将其用于边缘情况。所以符合以下条件:

在您的Revision中:

/**

* @ORM\ManyToOne(targetEntity="Page", cascade="persist")

* @ORM\JoinColumn(name="page_id", referencedColumnName="id", onDelete="SET NULL")

*/

private $parentPage;

/**

* @var int

* @ORM\Column(type="integer", name="removed_page_id", nullable=true)

*/

protected $removedPageId;

然后在您的Page中:

/**

* @ORM\PreRemove

*/

public function preRemovePageHandler(LifecycleEventArgs $args)

{

$entityManager = $args->getEntityManager();

$page = $args->getEntity();

$revisions = $page->getRevisions();

foreach($revisions as $revision){

$revision->setRemovedPageId($page->getId());

$entityManager->persist($revision);

}

$entityManager->flush();

}

或者,您当然可以在构造Revision的过程中已经设置了正确的$removedPageId值,那么您甚至不需要在remove上执行生命周期回调。

保证的约束要求额外的计算资源。 应用程序服务器比数据库服务器更易于水平扩展,因此应将约束放在业务逻辑中。

您明确要求数据不一致,但是我敢肯定您确实不希望这样做。我无法想到这种情况是可以辩护的。这是一个不好的做法,肯定会引起问题。例如:$revision->getPage()的预期结果是什么?

有一个非常简单而优雅的解决方案:可软删除。基本上,它为您的实体添加了一个名为deletedAt的属性(换句话说:向表中添加了列),以存储是否(或最好是:何时)删除该实体。因此,如果该属性为null,则不会删除该实体。

唯一要做的就是添加此捆绑包,向您的实体(Gedmo\SoftDeleteable\Traits\SoftDeleteableEntity)添加特征,并更新数据库。实现非常简单:此程序包将为您完成工作。阅读文档以了解此扩展。

或者,您可以添加"已启用"布尔值属性或状态字段(例如"已发布","草稿","已删除")。

When I delete the page I don't want to delete the revisions. I also want to keep the page_id on the page revisions (i.e. not set it to null).

我认为您已经得到了答案:教条不会这样做,仅仅是因为它与外键的概念无关。 FK的原理是确保数据一致性,因此,如果您有FK,则必须引用现有ID。删除时,某些数据库引擎(例如,用于MySQL的InnoDB)允许您将FK放入null(假设您确实使FK列可为空)。但是,引用不存在的ID是不可行的,或者它不是FK。

如果您确实想这样做,请不要在这种情况下使用Doctrine,这不会阻止您在代码库的其他地方使用Doctrine。另一种解决方案是仅手动将FK约束放到后面,或在查询之前使用DB语句跳过FK检查。

MySQL不是数据库引擎,而是DBMS。 MySQL的流行数据库引擎(InnoDB和MyISAM)与外键的处理方式不同。 如果您想了解更多信息,请阅读以下问题:stackoverflow.com/questions/12614541/

没错,经过修改可以反映出这一点

以及如何手动将FK约束放到后面?

$objectManager->getConnection()->exec(SET FOREIGN_KEY_CHECKS = 0;);

您可以禁用特定模型的外键导出:

User:

attributes:

export: tables

columns:

现在,它将仅导出表定义,不导出任何外键。您可以使用:无,表,约束,插件或全部。

php设置外键约束,关于php:禁用教义外键约束相关推荐

  1. mysql删除表外键_MySQL删除所有表的外键约束、禁用外键约束

    数据库的外键虽然能保证数据数据一致性和完整性,但是也一定程度地影响了数据更新的性能.在开发中,我们使用PowerDesigner建立物理数据模型时,为了结构的清晰,增加可读性,会创建表与表之间的关联关 ...

  2. mysql外键约束语句级连_mysql之外键约束(级联操作等) 父表子表

    不理解的地方标注问号. 网上不同的博客讲的,之间似乎有些矛盾,求推荐好书. 写得不好请指出错误. 父表和子表 当两个表建立一对多关系的时候,"一"的那一端是父表,"多&q ...

  3. mysql外键约束分数_MySQL提高(外键约束)

    外键约束 1.条件语句的写法 在sql中可以通过'where 条件语句' 来对操作对象进行筛选 -筛选 a.比较运算符:=,<>,,<=,>= 注意:判断一个字段的值是否为空不 ...

  4. mysql 外键 失败_存在外键时,MySQL 5.5外键约束失败

    刚在Mac OS X 10.6上安装了MySQL 5.5,并且在许多表上都有一个奇怪的问题.下面是一个例子.插入行失败,但不应插入外键约束.它引用的外键确实存在.有任何想法吗? mysql> s ...

  5. mysql外键约束案例_SQLServer FOREIGN KEY外键约束讲解及使用实例

    FOREIGN KEY约束添加规则 1.外键约束并不仅仅可以与另一表的主键约束相链接,它还可以定义为引用另一个表中 UNIQUE 约束的列. 2.如果在 FOREIGN KEY 约束的列中输入非 NU ...

  6. mysql中外键的作用是什么_mysql外键基本功能与用法详解

    本文实例讲述了mysql外键基本功能与用法.分享给大家供大家参考,具体如下: 本文内容: 什么是外键 外键的增加 外键的修改和删除 外键的约束模式 首发日期:2018-04-12 什么是外键: 外键就 ...

  7. Oracle数据库-主键(primary key)、外键(foreign key)、候选键(candidate key)、超键(super key)和references总结...

    主要介绍一下个人对主键(primary key).外键(foreign key).候选键(Candidate key).超键(super key).references的总结 概念: 主键:用户选择元 ...

  8. mysql中主键的用法_MySQL中的主键以及设置其自增的用法教程

    1.声明主键的方法:您可以在创建表的时候就为表加上主键,如: CREATE TABLE tbl_name ([字段描述省略...], PRIMARY KEY(index_col_name)); 也可以 ...

  9. oracle外建什么作用,列举在数据库中外键的好处以及优劣

    外键的好处: 1减少重复数据 在删除主表数据前先删除与之相关的子表的相关数据 原则上主表的数据是不允许删除的 2可以设置级联删除和更新,保证数据库的完整性 3外键在一定程度上说明了业务逻辑,会使设计周 ...

最新文章

  1. RSA公钥格式PKCS#1,PKCS#8互转(微信获取RSA加密公钥)
  2. mongodb创建用户和密码
  3. linux复制文件夹 实例,linux复制文件夹与文件实例介绍linux操作系统 -电脑资料
  4. haroopad设置
  5. JVM PermGen –您在哪里?
  6. Linux API函数总结
  7. 字节跳动武汉招聘 2000 人,距离大厂 Offer,你还差这篇 Java 干货!| 原力计划...
  8. zabbix报错cannot set resource limit: [13] Permission denied解决方法
  9. 使用virtualenv和pip构建项目所需的独立Python环境
  10. mysql isamchk_mysqlcheck与myisamchk的区别
  11. python核心编程第13章答案
  12. Ubuntu安装sasquatch时执行./build.sh报错:--no-check-certificate
  13. 计算机课word实验总结,大学计算机操作实践报告【实验8】Word2010综合实验
  14. 使用petalinux编译工程,报错:Unable to parse input tree,已解决
  15. mysql如何避免单点故障
  16. 8.0.高等数学3-向量的乘法运算(数量积、向量积与混合积)
  17. 【数学】对向量的求导和Jacobian矩阵的几何意义与Hessian矩阵
  18. 使用 Shell 运算进行进制转换 16进制转10进制
  19. Swift语言官方文档翻译(1)
  20. Redis框架从入门到学精(全)

热门文章

  1. 基于深度神经网络的噪声标签学习
  2. 【华为云技术分享】【DevCloud· 敏捷智库】物理看板和电子看板该如何选择?(内附下载材料)
  3. 机器学习笔记(十)---- KNN(K Nearst Neighbor)
  4. 带着canvas去流浪系列之六 绘制雷达图
  5. 设计模式的C语言应用-非典型模式-第十章
  6. Hadoop的RPC工作原理
  7. 数据结构 多路查找树 ---------B树和B+树的简单介绍
  8. vs2019配置OpenGL
  9. 打开Jupyter Notebook 时报错:EnvironmentLocationNotFound: Not a conda environment:
  10. pycharm在运行TensorFlow时出现如下信息