def _create_columns(new_columns, context): """Add new_columns just created to the DB in the given context. :param new_columns: List of columns that have been already created :param context: Dictionary to pass the serializer with extra info :return: List of new column objects """ if not new_columns: return [] workflow = context['workflow'] # There are some new columns that need to be created column_data = ColumnSerializer(data=new_columns, many=True, context=context) # And save its content if not column_data.is_valid(): raise Exception(_('Unable to create column data')) new_columns = column_data.save() # Add columns to DB for col in new_columns: add_column_to_db(workflow.get_data_frame_table_name(), col.name, col.data_type) # Update the column position and count in the workflow workflow.ncols = workflow.ncols + 1 col.position = workflow.ncols col.save() workflow.save() return new_columns
class ActionSelfcontainedSerializer(ActionSerializer): """Full Action serializer traversing conditions AND columns.""" used_columns = ColumnSerializer(many=True, required=False) def create(self, validated_data, **kwargs): """Create the Action object with the validated data.""" if not self.context['workflow'].has_data_frame(): # Cannot create columns with an empty workflow raise Exception( _('Unable to import action ' + ' in a workflow with and empty data table')) new_columns = [] try: new_columns = _process_columns(validated_data['used_columns'], self.context) # Create the action, conditions and columns/condition-column pairs action_obj = super().create(validated_data, **kwargs) except Exception: if new_columns: for col in new_columns: col.delete() raise return action_obj class Meta(object): """Define the model and the field to exclude.""" model = Action exclude = ('id', 'workflow', 'created', 'modified', 'last_executed_log')
class WorkflowExportSerializer(serializers.ModelSerializer): """Serializer to export the workflow. This serializer is use to export Workflows selecting a subset of actions. Since the SerializerMethodField used for the selection is a read_only field, the import is managed by a different serializer that uses a regular one for the action field (see WorkflowImportSerializer) """ actions = serializers.SerializerMethodField() data_frame = DataFramePandasField( required=False, allow_null=True, help_text=_('This field must be the Base64 encoded ' + 'result of pandas.to_pickle() function'), ) columns = ColumnSerializer(many=True, required=False) views = ViewSerializer(many=True, required=False) version = serializers.CharField(read_only=True, default='NO VERSION', allow_blank=True, label='OnTask Version', help_text=_('To guarantee compability')) def get_actions(self, workflow: models.Workflow) -> List[models.Action]: """Get the list of selected actions.""" action_list = self.context.get('selected_actions', []) if not action_list: # No action needs to be included, no need to call the action # serializer return [] # Execute the query set query_set = workflow.actions.filter(id__in=action_list) # Serialize the content and return data serializer = ActionSerializer(instance=query_set, many=True, required=False) return serializer.data @profile def create(self, validated_data, **kwargs): """Create the new workflow.""" wflow_name = self.context.get('name') if not wflow_name: wflow_name = self.validated_data.get('name') if not wflow_name: raise Exception(_('Unexpected empty workflow name.')) if models.Workflow.objects.filter( name=wflow_name, user=self.context['user']).exists(): raise Exception( _('There is a workflow with this name. ' + 'Please provide a workflow name in the import page.')) # Initial values workflow_obj = None try: workflow_obj = models.Workflow( user=self.context['user'], name=wflow_name, description_text=validated_data['description_text'], nrows=0, ncols=0, attributes=validated_data['attributes'], query_builder_ops=validated_data.get('query_builder_ops', {}), ) workflow_obj.save() # Create the columns column_data = ColumnSerializer(data=validated_data.get( 'columns', []), many=True, context={'workflow': workflow_obj}) # And save its content if column_data.is_valid(): columns = column_data.save() else: raise Exception(_('Unable to save column information')) # If there is any column with position = 0, recompute (this is to # guarantee backward compatibility. if any(col.position == 0 for col in columns): for idx, col in enumerate(columns): col.position = idx + 1 col.save() # Load the data frame data_frame = validated_data.get('data_frame') if data_frame is not None: # Store the table in the DB pandas.store_table( data_frame, workflow_obj.get_data_frame_table_name(), dtype={ col.name: col.data_type for col in workflow_obj.columns.all() }, ) # Reconcile now the information in workflow and columns with # the one loaded workflow_obj.ncols = validated_data['ncols'] workflow_obj.nrows = validated_data['nrows'] workflow_obj.save() # Create the actions pointing to the workflow action_data = ActionSerializer(data=validated_data.get( 'actions', []), many=True, context={ 'workflow': workflow_obj, 'columns': columns }) if action_data.is_valid(): action_data.save() else: raise Exception(_('Unable to save column information')) # Create the views pointing to the workflow view_data = ViewSerializer(data=validated_data.get('views', []), many=True, context={ 'workflow': workflow_obj, 'columns': columns }) if view_data.is_valid(): view_data.save() else: raise Exception(_('Unable to save column information')) except Exception: # Get rid of the objects created if workflow_obj: if workflow_obj.id: workflow_obj.delete() raise return workflow_obj class Meta: """Select model and fields to exclude.""" model = models.Workflow exclude = ( 'id', 'user', 'created', 'modified', 'data_frame_table_name', 'session_key', 'shared', 'star', 'luser_email_column', 'luser_email_column_md5', 'lusers', 'lusers_is_outdated', )
def create(self, validated_data, **kwargs): """Create the new workflow.""" wflow_name = self.context.get('name') if not wflow_name: wflow_name = self.validated_data.get('name') if not wflow_name: raise Exception(_('Unexpected empty workflow name.')) if models.Workflow.objects.filter( name=wflow_name, user=self.context['user']).exists(): raise Exception( _('There is a workflow with this name. ' + 'Please provide a workflow name in the import page.')) # Initial values workflow_obj = None try: workflow_obj = models.Workflow( user=self.context['user'], name=wflow_name, description_text=validated_data['description_text'], nrows=0, ncols=0, attributes=validated_data['attributes'], query_builder_ops=validated_data.get('query_builder_ops', {}), ) workflow_obj.save() # Create the columns column_data = ColumnSerializer(data=validated_data.get( 'columns', []), many=True, context={'workflow': workflow_obj}) # And save its content if column_data.is_valid(): columns = column_data.save() else: raise Exception(_('Unable to save column information')) # If there is any column with position = 0, recompute (this is to # guarantee backward compatibility. if any(col.position == 0 for col in columns): for idx, col in enumerate(columns): col.position = idx + 1 col.save() # Load the data frame data_frame = validated_data.get('data_frame') if data_frame is not None: # Store the table in the DB pandas.store_table( data_frame, workflow_obj.get_data_frame_table_name(), dtype={ col.name: col.data_type for col in workflow_obj.columns.all() }, ) # Reconcile now the information in workflow and columns with # the one loaded workflow_obj.ncols = validated_data['ncols'] workflow_obj.nrows = validated_data['nrows'] workflow_obj.save() # Create the actions pointing to the workflow action_data = ActionSerializer(data=validated_data.get( 'actions', []), many=True, context={ 'workflow': workflow_obj, 'columns': columns }) if action_data.is_valid(): action_data.save() else: raise Exception(_('Unable to save column information')) # Create the views pointing to the workflow view_data = ViewSerializer(data=validated_data.get('views', []), many=True, context={ 'workflow': workflow_obj, 'columns': columns }) if view_data.is_valid(): view_data.save() else: raise Exception(_('Unable to save column information')) except Exception: # Get rid of the objects created if workflow_obj: if workflow_obj.id: workflow_obj.delete() raise return workflow_obj