当前位置: 首页 > 知识库问答 >
问题:

如何清理Django孤立外键值?

胡鸿羲
2023-03-14

我正在创建一个模型,该模型引用第三方包——芹菜(Crontab时间表和周期任务)中的模型。我的模型(让我们称之为SchduledRun)将包含一个周期任务的外键。

我知道,如果我删除外键本身,就会发生级联删除,引用该外键的父级也会被删除。(除非在删除时被覆盖…)

但由于我将ScheduledRun指向PeriodicTask的FK,所以在删除ScheduledRun时,PeriodicTask不会自动删除。(也不应该这样做,因为可能有其他模型指向该外键!)

那么,我如何清理那些孤立的任务呢?也就是说,当不再有模型实例指向它的时候。

我可以添加一个post_delete信号并以这种方式检查它(这个例子是删除与周期性任务不再相关的无关CrontabSchedules:

# periodictask below is actually a related periodictask_set, 
# but in Django you refer to the empty set as 'periodictask=None'
CrontabSchedule.objects.filter(id=instance.crontab.id,
                               periodictask=None).delete()

但我不能保证没有其他相关关系会导致级联下降。

我可以子类化的表周期任务为schduledRun......但宁愿不与第三方模型紧密集成。

这就好像我想要一个.delete(do_not_cascade=True),如果它由于约束而失败,只需忽略失败。如果它成功了,那么它就是一个孤儿。on_delete=DO_与此类似,但我只想在单个删除的范围内暂时打开它,不想修改第三方包。

有没有其他/更好的方法来处理这个问题?

共有1个答案

和嘉澍
2023-03-14

这是我的解决方案。。。看起来它可能足够强大了。我的目标是仅在没有其他模型实例仍然引用外键值时删除它。

所以,我将尝试删除基于每个相关的键值为无:

# This is a class method to my ScheduledRun class that has
# a foreign key to a PeriodicTask.  PeriodicTask has a 
# FK to a CrontabSchedule, which I'd like to "trim"
# if nothing points to that FK anymore.
@classmethod
def _post_delete(cls, instance, **kwargs):
    instance.periodic_task.delete()
    # Delete the crontab if no other tasks point to it.
    # This could cause a cascade if we don't check all related...
    filter = dict(id=instance.crontab.id)
    for related in instance.crontab._meta.get_all_related_objects():
        filter[related.var_name] = None
    assert('id' in filter)
    assert('schedule' in filter)
    assert('periodictask' in filter)
    CrontabSchedule.objects.filter(**filter).delete()

如果我可以说:

instance.crontab.delete(NO_CASCADE=True)
 类似资料:
  • 问题内容: 我在一个大型组织中工作,该组织在一个共享的Jenkins集群中运行数百个工作。 我的Jenkins工作需要针对Docker容器中运行的不受信任的代码运行集成测试。我担心当我的詹金斯(Jenkins)工作突然终止(例如,工作中止或超时)时,我将身处孤儿容器中。 我已经尝试过https://github.com/moby/moby/issues/1905,但它对我不起作用(这是因为它仅适用

  • 我的应用程序使用了一个键控窗口,该窗口由时间戳函数键控。这意味着一旦该特定窗口被激发和处理,保持该键活动就没有用了,因为该特定键不会再次出现。因为这个用例涉及到持续扩展键,所以我想在一个键完成处理后立即清除它的状态,而不必配置计时器。 在每个键控窗口完成处理后,这是否可以在方法或方法中实现?

  • 问题内容: 我有一个html: 我想按顺序获取所有文本,例如以下数组: 问题答案: 我将使用一种递归方法,该方法采用您的开始标记并对其子节点进行迭代。对于每个TextNode,打印内容。对于每个元素,检查它的子节点。 输出量

  • 问题内容: 一般来说,我对Web应用程序和数据库内容还是陌生的,所以这可能是一个愚蠢的问题。我想制作一个模型(“ CategoryModel”),其字段指向模型的另一个实例(其父实例)的主要ID。 我该怎么做呢?谢谢! 问题答案: 您可以将模型的名称作为字符串传递给ForeignKey,它将做正确的事情。 所以: 或者您可以使用字符串“ self”

  • 我正在为Django管理员设置: model.py 在admin.py 对此,我得到了以下错误: (admin. E202)“磁盘。文件”没有“磁盘。设置”的外键 根据https://docs . django project . com/en/dev/ref/models/fields/# django . db . models . foreign key中的文档,它应该可以工作。 我做了一些

  • 我使用Atomikos事务管理器管理Spring-Boot独立应用程序中的分布式事务,使用Apache Camel集成ActiveMQ队列和postgresql DB(JPA via Hibernate5)。我的问题是在我的日志中打印了很多类似下面这样的消息。 为什么一直打印这些日志? 我认为超时(ActiveMQ组件、Datasource或Atomikos)配置不佳,但我不知道如何开始研究它。