Esempio n. 1
0
    def num_rows(self):
        """
        Number of rows considered by this view
        :return: Number of rows resulting from using the formula
        """
        if not self.nrows:
            self.nrows = sql.get_num_rows(
                self.workflow.get_data_frame_table_name(), self.formula)

        return self.nrows
Esempio n. 2
0
    def update_n_rows_selected(self, column=None, filter_formula=None):
        """Calculate the number of rows for which condition is true.

        Given a condition update the number of rows
        for which this condition will have true result.

        :param column: Column that has changed value (None when unknown)
        :param filter_formula: Formula provided by another filter condition
        and to take the conjunction with the condition formula.
        :return: Nothing. Effect recorded in DB objects
        """
        if column and column not in self.columns.all():
            # The column is not part of this condition. Nothing to do
            return

        formula = self.formula
        if filter_formula:
            # There is a formula to add to the condition, create a conjunction
            formula = {
                'condition': 'AND',
                'not': False,
                'rules': [filter_formula, self.formula],
                'valid': True,
            }

        new_count = get_num_rows(
            self.action.workflow.get_data_frame_table_name(),
            formula,
        )
        if new_count != self.n_rows_selected:
            # Reset the field in the action storing rows with all conditions
            # false. Needs to be recalculated because there is at least one
            # condition that has changed its count. Flush the field to None
            self.action.rows_all_false = None
            self.action.save()

        self.n_rows_selected = new_count
        self.save()
Esempio n. 3
0
def store_workflow_table(
    workflow,
    update_info: Optional[Dict] = None,
):
    """Make a temporary DB table the workflow table.

    It is assumed that there is a temporal table already in the database. The
    function performs the following steps:

    Step 1: Drop the columns that are not being uploaded

    Step 2: Rename the columns (if needed)

    Step 3: Create the workflow columns

    Step 4: Rename the table (temporary to final)

    Step 5: Update workflow fields and update

    :param workflow: Workflow object being manipulated.
    :param update_info: Dictionary with the following fields:
        - initial_column_names: list of column names detected in read phase.
        - rename_column_names: List of new names for the columns
        - column_types: List of types detected after storing in DB
        - keep_key_column: List of booleans to flag if key property is kept
        - columns_to_upload: List of booleans to flag column upload
        The first field is mandatory. The have default values if not provided.
    :return: Nothing. Anomalies are raised as Exceptions
    """
    # Check information on update_info and complete if needed
    if not update_info.get('initial_column_names'):
        raise _('Internal error while processing database.')
    if not update_info.get('rename_column_names'):
        update_info['rename_column_names'] = update_info[
            'initial_column_names']
    if not update_info.get('column_types'):
        raise _('Internal error while processing database.')
    if not update_info.get('keep_key_column'):
        raise _('Internal error while processing database.')
    if not update_info.get('columns_to_upload'):
        update_info['columns_to_upload'] = [True] * len(
            update_info['initial_column_names'])

    db_table = workflow.get_upload_table_name()
    new_columns = []
    for old_n, new_n, data_type, is_key, upload in zip(
            update_info['initial_column_names'],
            update_info['rename_column_names'],
            update_info['column_types'],
            update_info['keep_key_column'],
            update_info['columns_to_upload'],
    ):
        # Detect if the column is new or already exists
        current_col = workflow.columns.filter(name=old_n).first()

        # Step 1: Check if column needs to be uploaded
        if not upload:
            # Column is dropped
            sql.df_drop_column(db_table, old_n)

            if current_col:
                # Dropping an existing column. Incorrect.
                raise _('Invalid column drop operation.')
            continue

        # Step 2: Check if the column must be renamed
        if old_n != new_n:
            # Rename column from old_n to new_n
            sql.db_rename_column(db_table, old_n, new_n)

            if current_col:
                rename_df_column(workflow, old_n, new_n)

        if current_col:
            if current_col.data_type != data_type:
                # If the column type in the DB is different from the one in the
                # object, update
                current_col.data_type = data_type
                current_col.save()
        else:
            # Step 3: Create the column
            new_columns.append((new_n, data_type, is_key))

    # Create the columns
    workflow.add_columns(new_columns)
    workflow.refresh_from_db()

    # Step 4: Rename the table (Drop the original one first
    if workflow.has_table():
        sql.delete_table(workflow.get_data_frame_table_name())
    sql.rename_table(db_table, workflow.get_data_frame_table_name())

    # Step 5: Update workflow fields and save
    workflow.nrows = sql.get_num_rows(workflow.get_data_frame_table_name())
    workflow.set_query_builder_ops()
    workflow.save(update_fields=['nrows', 'query_builder_ops'])