Skip to content

Commit

Permalink
Migrate default values in node migration #37
Browse files Browse the repository at this point in the history
  • Loading branch information
johnatawnclementawn committed Nov 12, 2024
1 parent 90670e7 commit 038914b
Showing 1 changed file with 61 additions and 46 deletions.
107 changes: 61 additions & 46 deletions arches_references/management/commands/controlled_lists.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from arches.app.datatypes.datatypes import DataTypeFactory
from arches.app.models.fields.i18n import I18n_JSONField
from arches.app.models.graph import Graph
from arches.app.models.models import (
CardXNodeXWidget,
GraphModel,
Expand All @@ -7,7 +9,6 @@
Value,
Widget,
)
from arches.app.models.graph import Graph
from arches_references.models import List
from django.core.exceptions import ValidationError
from django.core.management.base import BaseCommand, CommandError
Expand Down Expand Up @@ -195,6 +196,12 @@ def migrate_concept_nodes_to_reference_datatype(self, graph):
)
)
.prefetch_related("cardxnodexwidget_set")
.annotate(
widget_config=Cast(
models.F("cardxnodexwidget__config"),
output_field=models.JSONField(),
)
)
)

if len(nodes) == 0:
Expand All @@ -205,12 +212,29 @@ def migrate_concept_nodes_to_reference_datatype(self, graph):
)

REFERENCE_SELECT_WIDGET = Widget.objects.get(name="reference-select-widget")
REFERENCE_FACTORY = DataTypeFactory().get_instance("reference")
controlled_list_ids = List.objects.all().values_list("id", flat=True)

errors = []
with transaction.atomic():
for node in nodes:
if node.collection_id in controlled_list_ids:
# Check that collections have been migrated to controlled lists
for node in nodes:
if node.collection_id not in controlled_list_ids:
errors.append(
{"node_alias": node.alias, "collection_id": node.collection_id}
)
if errors:
self.stderr.write(
"The following collections for the associated nodes have not been migrated to controlled lists:"
)
for error in errors:
self.stderr.write(
"Node alias: {0}, Collection ID: {1}".format(
error["node_alias"], error["collection_id"]
)
)
else:
with transaction.atomic():
for node in nodes:
if node.datatype == "concept":
node.config = {
"multiValue": False,
Expand All @@ -225,60 +249,51 @@ def migrate_concept_nodes_to_reference_datatype(self, graph):
node.full_clean()
node.save()

cross_records = (
node.cardxnodexwidget_set.annotate(
config_without_i18n=Cast(
models.F("config"),
output_field=models.JSONField(),
)
)
.annotate(
without_default=CombinedExpression(
models.F("config_without_i18n"),
"-",
models.Value(
"defaultValue", output_field=models.CharField()
),
output_field=models.JSONField(),
)
cross_records = node.cardxnodexwidget_set.annotate(
config_without_i18n=Cast(
models.F("config"),
output_field=models.JSONField(),
)
.annotate(
without_default_and_options=CombinedExpression(
models.F("without_default"),
"-",
models.Value(
"options", output_field=models.CharField()
),
output_field=I18n_JSONField(),
)
).annotate(
config_without_options=CombinedExpression(
models.F("config_without_i18n"),
"-",
models.Value("options", output_field=models.CharField()),
output_field=I18n_JSONField(),
)
)
for cross_record in cross_records:
# work around for i18n as_sql method issue detailed here: https://github.com/archesproject/arches/issues/11473
cross_record.config = {}
cross_record.save()

cross_record.config = cross_record.without_default_and_options
# Crosswalk concept version of default values to reference versions
original_default_value = (
cross_record.config_without_options.get(
"defaultValue", None
)
)
if original_default_value:
new_default_value = []
if isinstance(original_default_value, str):
original_default_value = [original_default_value]
for value in original_default_value:
value_rec = Value.objects.get(pk=value)
config = {"controlledList": node.collection_id}
new_value = REFERENCE_FACTORY.transform_value_for_tile(
value=value_rec.value,
**config,
)
new_default_value.append(new_value[0])
cross_record.config_without_options["defaultValue"] = (
new_default_value
)

cross_record.config = cross_record.config_without_options
cross_record.widget = REFERENCE_SELECT_WIDGET
cross_record.full_clean()
cross_record.save()

elif node.collection_id not in controlled_list_ids:
errors.append(
{"node_alias": node.alias, "collection_id": node.collection_id}
)

if errors:
self.stderr.write(
"The following collections for the associated nodes have not been migrated to controlled lists:"
)
for error in errors:
self.stderr.write(
"Node alias: {0}, Collection ID: {1}".format(
error["node_alias"], error["collection_id"]
)
)
else:
source_graph = Graph.objects.get(pk=graph_id)

# Refresh the nodes to ensure the changes are reflected in the serialized graph
Expand Down

0 comments on commit 038914b

Please sign in to comment.