Ejemplo n.º 1
0
    def setUpBeforeMigration(self):
        from aiida.common.utils import get_new_uuid
        self.file_name = 'test.temp'
        self.file_content = '#!/bin/bash\n\necho test run\n'

        self.nodes_boolean = []
        self.nodes_integer = []
        self.n_bool_duplicates = 2
        self.n_int_duplicates = 4

        node_bool = self.DbNode(type='data.bool.Bool.',
                                user_id=self.default_user.id,
                                uuid=get_new_uuid())
        node_bool.save()

        node_int = self.DbNode(type='data.int.Int.',
                               user_id=self.default_user.id,
                               uuid=get_new_uuid())
        node_int.save()

        self.nodes_boolean.append(node_bool)
        self.nodes_integer.append(node_int)

        for _ in range(self.n_bool_duplicates):
            node = self.DbNode(type='data.bool.Bool.',
                               user_id=self.default_user.id,
                               uuid=node_bool.uuid)
            node.save()
            utils.put_object_from_string(node.uuid, self.file_name,
                                         self.file_content)
            self.nodes_boolean.append(node)

        for _ in range(self.n_int_duplicates):
            node = self.DbNode(type='data.int.Int.',
                               user_id=self.default_user.id,
                               uuid=node_int.uuid)
            node.save()
            utils.put_object_from_string(node.uuid, self.file_name,
                                         self.file_content)
            self.nodes_integer.append(node)

        # Verify that there are duplicate UUIDs by checking that the following function raises
        with self.assertRaises(IntegrityError):
            verify_uuid_uniqueness(table='db_dbnode')

        # Now run the function responsible for solving duplicate UUIDs which would also be called by the user
        # through the `verdi database integrity detect-duplicate-uuid` command
        deduplicate_uuids(table='db_dbnode', dry_run=False)
Ejemplo n.º 2
0
def detect_duplicate_uuid(table, apply_patch):
    """Detect and fix entities with duplicate UUIDs.

    Before aiida-core v1.0.0, there was no uniqueness constraint on the UUID column of the node table in the database
    and a few other tables as well. This made it possible to store multiple entities with identical UUIDs in the same
    table without the database complaining. This bug was fixed in aiida-core=1.0.0 by putting an explicit uniqueness
    constraint on UUIDs on the database level. However, this would leave databases created before this patch with
    duplicate UUIDs in an inconsistent state. This command will run an analysis to detect duplicate UUIDs in a given
    table and solve it by generating new UUIDs. Note that it will not delete or merge any rows.
    """
    from aiida.manage.database.integrity.duplicate_uuid import deduplicate_uuids
    from aiida.manage.manager import get_manager

    manager = get_manager()
    manager._load_backend(schema_check=False)  # pylint: disable=protected-access

    try:
        messages = deduplicate_uuids(table=table, dry_run=not apply_patch)
    except Exception as exception:  # pylint: disable=broad-except
        echo.echo_critical('integrity check failed: {}'.format(str(exception)))
    else:
        for message in messages:
            echo.echo_info(message)

        if apply_patch:
            echo.echo_success('integrity patch completed')
        else:
            echo.echo_success('dry-run of integrity patch completed')