Skip to content

Commit

Permalink
Use json instead of jsonb to preserver parameter order
Browse files Browse the repository at this point in the history
  • Loading branch information
hdoupe committed Apr 6, 2020
1 parent 59f9171 commit 0781473
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Generated by Django 3.0.3 on 2020-03-27 17:00
# Generated by Django 3.0.3 on 2020-04-06 20:47

import django.contrib.postgres.fields.jsonb
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import webapp.apps.comp.models


class Migration(migrations.Migration):
Expand Down Expand Up @@ -44,14 +45,8 @@ class Migration(migrations.Migration):
"meta_parameters_values",
django.contrib.postgres.fields.jsonb.JSONField(null=True),
),
(
"meta_parameters",
django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
(
"model_parameters",
django.contrib.postgres.fields.jsonb.JSONField(default=dict),
),
("meta_parameters", webapp.apps.comp.models.JSONField(default=dict)),
("model_parameters", webapp.apps.comp.models.JSONField(default=dict)),
(
"project",
models.ForeignKey(
Expand Down
29 changes: 17 additions & 12 deletions webapp/apps/comp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from django.shortcuts import get_object_or_404
from django.utils.functional import cached_property
from django.utils import timezone
from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.fields import JSONField as JSONBField
from django.contrib.auth.models import Group
from django.urls import reverse
from django.utils import timezone
Expand All @@ -40,6 +40,11 @@
)


class JSONField(JSONBField):
def db_type(self, connection):
return "json"


class ModelConfigManager(models.Manager):
def get(self, project, model_version, meta_parameters_values, **kwargs):
if meta_parameters_values:
Expand All @@ -66,7 +71,7 @@ class ModelConfig(models.Model):
)
creation_date = models.DateTimeField(default=timezone.now)

meta_parameters_values = JSONField(null=True)
meta_parameters_values = JSONBField(null=True)
meta_parameters = JSONField(default=dict)
model_parameters = JSONField(default=dict)

Expand All @@ -91,18 +96,18 @@ class Inputs(models.Model):
null=True,
related_name="inputs_instances",
)
meta_parameters = JSONField(default=None, blank=True, null=True)
raw_gui_inputs = JSONField(default=None, blank=True, null=True)
gui_inputs = JSONField(default=None, blank=True, null=True)
meta_parameters = JSONBField(default=None, blank=True, null=True)
raw_gui_inputs = JSONBField(default=None, blank=True, null=True)
gui_inputs = JSONBField(default=None, blank=True, null=True)

# Validated GUI input that has been parsed to have the correct data types,
# or JSON reform uploaded as file
custom_adjustment = JSONField(default=dict, blank=True, null=True)
custom_adjustment = JSONBField(default=dict, blank=True, null=True)

errors_warnings = JSONField(default=None, blank=True, null=True)
errors_warnings = JSONBField(default=None, blank=True, null=True)

# The parameters that will be used to run the model
adjustment = JSONField(default=dict, blank=True, null=True)
adjustment = JSONBField(default=dict, blank=True, null=True)

# If project changes input type, we still want to know the type of the
# previous model runs' inputs.
Expand Down Expand Up @@ -339,15 +344,15 @@ class Simulation(models.Model):
# TODO: dimension needs to go
dimension_name = "Dimension--needs to go"
title = models.CharField(default="Untitled Simulation", max_length=500)
readme = JSONField(null=True, default=None, blank=True)
readme = JSONBField(null=True, default=None, blank=True)
last_modified = models.DateTimeField(default=timezone.now)
parent_sim = models.ForeignKey(
"self", null=True, related_name="child_sims", on_delete=models.SET_NULL
)
inputs = models.OneToOneField(Inputs, on_delete=models.CASCADE, related_name="sim")
meta_data = JSONField(default=None, blank=True, null=True)
outputs = JSONField(default=None, blank=True, null=True)
aggr_outputs = JSONField(default=None, blank=True, null=True)
meta_data = JSONBField(default=None, blank=True, null=True)
outputs = JSONBField(default=None, blank=True, null=True)
aggr_outputs = JSONBField(default=None, blank=True, null=True)
traceback = models.CharField(null=True, blank=True, default=None, max_length=8000)
owner = models.ForeignKey(
"users.Profile", on_delete=models.CASCADE, null=True, related_name="sims"
Expand Down
22 changes: 22 additions & 0 deletions webapp/apps/comp/tests/test_model_parameters.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import copy

import pytest
import requests_mock
import paramtools as pt
Expand Down Expand Up @@ -133,3 +135,23 @@ def test_model_parameters(mock_project):
# test going back to init doesn't break cache
defaults = mp.defaults()
assert ModelConfig.objects.filter(project=project).count() == 2


def test_parameter_order(monkeypatch, mock_project):
project = mock_project
new_defaults = copy.deepcopy(Params.defaults)
for i in range(50):
new_defaults[f"param-{i}"] = copy.deepcopy(new_defaults["param"])

monkeypatch.setattr(Params, "defaults", new_defaults)

mp = ModelParameters(project=mock_project)
mp.get_inputs()

mc = ModelConfig.objects.get(
project=project, model_version="v1", meta_parameters_values={}
)

params = Params()
for act, exp in zip(mc.model_parameters["section"], params.dump()):
assert act == exp, f"Expected {act} === {exp}"
2 changes: 1 addition & 1 deletion webapp/apps/publish/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def test_put_detail_api(self, client, test_models, profile, password):
title="Used-for-testing", owner__user__username="modeler"
)
assert project.description == put_data["description"]
assert project.status == "updating"
assert project.status == "live"

# Description can't be empty.
resp = client.put(
Expand Down

0 comments on commit 0781473

Please sign in to comment.