Reputation: 67
I implemented the storage of one-to-many models through a view. The model structure is as follows:
So as follows, I Create all the instances first, to make sure there are no errors, and only in the very end, I persist them using save(). But this returns
django.db.utils.IntegrityError: NOT NULL constraint failed:
[28/Jul/2017 11:56:12] "POST /task/run HTTP/1.1" 500 19464
And this is the code of how I create the models and persist them in the end
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()
If I instead decide to save them as I create them, this code works fine. So it looks like Foreign Keys can only be used once models are persisted, and this might be risked if my models fail to be created later in the hierarchy.
Is there any safer approach?
Upvotes: 1
Views: 63
Reputation: 8026
You may want to use a transaction so that you can enforce an "everything gets saved or nothing does" type of behavior. This would be the safest approach in my opinion.
Upvotes: 3
Reputation: 764
There really isn't beyond finding ways to simplify the relationships between your models.
A ForeignKey
relationship can't be safely established until the primary key of the related object is set. Otherwise, you could potentially kiss data integrity goodbye.
If you are deeply concerned about the possibility of failure somewhere along the chain, remember that you have access to the objects you just saved, and add error handling that deletes the entire chain of new objects on a failure and throws a useful error pointing out where the chain failed.
Upvotes: 1