使用外键安全地保留django模型

时间:2017-07-28 15:01:28

标签: python django django-models

我通过视图实现了一对多模型的存储。模型结构如下:

  • DagRun模型
  • 许多DagRunModel,它有一个FK到DagRun
  • 许多DagModelParam,它有一个FK到DagRunModel

如下所示,我首先创建所有实例,以确保没有错误,并且只在最后,我使用save()持久化它们。但是这会返回

django.db.utils.IntegrityError: NOT NULL constraint failed:
[28/Jul/2017 11:56:12] "POST /task/run HTTP/1.1" 500 19464

这是我如何创建模型并在最后坚持它们的代码

def task_run(request):
    dag_task = None
    dag_tasks = DagTask.objects.filter(dag_id=request.POST["task"])
    if len(dag_tasks) > 0:
        dag_task = dag_tasks[0]
    else:
        raise ValueError("Task name is not a valid dag id")

    dag_run = DagRun(
        dag_task=dag_task,
        database=request.POST["database"],
        table=request.POST["table"],
        label=request.POST["label"],
        features=request.POST["features"],
        user=request.user,
        date=timezone.now()
        )

    dag_params = []
    dag_models = []
    models = json.loads(request.POST["models"])
    for model in models:
        dag_run_model = DagRunModel(
            dag_run=dag_run,
            dag_model=model["name"]
            )
        dag_models.append(dag_run_model)
        for param in model["params"]:
            dag_param = DagRunParam(
                dag_run_model=dag_run_model,
                dag_param=param["name"],
                param_value=param["value"]
                )
            dag_params.append(dag_param)

    dag_run.save()
    for dag_model in dag_models:
        dag_model.save()
    for dag_param in dag_params:
        dag_param.save()

如果我决定在创建它们时保存它们,则此代码可以正常工作。因此,只有在持久化模型后才能使用外键,如果我的模型稍后无法在层次结构中创建,则可能会有风险。

有更安全的方法吗?

2 个答案:

答案 0 :(得分:3)

您可能希望使用transaction,以便您可以强制执行"所有内容都会被保存,或者什么都不会保存。行为类型。在我看来,这将是最安全的方法。

答案 1 :(得分:1)

确实没有找到简化模型之间关系的方法。

在设置相关对象的主键之前,无法安全地建立ForeignKey关系。否则,您可能会再次亲吻数据完整性。

如果您对链中某处出现故障的可能性深感担忧,请记住您可以访问刚刚保存的对象,并添加错误处理,在失败时删除整个新对象链并引发有用的错误指出链条失败的地方。