Example #1
0
def execute_upgrade():
    """Execute the upgrade from InvenioRDM 3.0 to 4.0.

    Please read the disclaimer on this module before thinking about executing
    this function!
    """
    def remove_duplicate_languages(record):
        """Remove duplicate languages."""
        if "languages" in record["metadata"]:
            serialized_languages = map(
                tuple,
                map(sorted, map(dict.items, record["metadata"]["languages"])),
            )
            unique_languages = set(serialized_languages)
            languages_list = list(map(dict, unique_languages))
            record["metadata"]["languages"] = languages_list

    def update_vocabularies(record):
        """Updates languages and resource_type to become vocabularies."""
        def get_res_type_vocabulary(data):
            """Returns the id value of the resource type vocabulary."""
            if "subtype" in data["resource_type"]:
                return data["resource_type"]["subtype"]
            elif "type" in data["resource_type"]:
                return data["resource_type"]["type"]

        def get_language_vocabulary(data):
            """Returns the language as vocabulary."""
            return dict(id=data)

        def migrate_language(field):
            """Migrates language field."""
            for idx, val in enumerate(record["metadata"].get(field, [])):
                if "lang" in val:
                    language_vocab = get_language_vocabulary(val["lang"])
                    record["metadata"][field][idx]["lang"] = language_vocab

        # Migrate resource_type
        if "resource_type" in record["metadata"]:
            res_type_vocab = get_res_type_vocabulary(record["metadata"])
            record["metadata"]["resource_type"] = dict(id=res_type_vocab)

        # Migrate resource_type of related_identifiers
        for idx, val in enumerate(record["metadata"].get(
                "related_identifiers", [])):
            if "resource_type" in val:
                res_type_vocab = get_res_type_vocabulary(val)
                record["metadata"]["related_identifiers"][idx][
                    "resource_type"] = dict(id=res_type_vocab)

        # Migrate languages from additional_descriptions
        migrate_language("additional_descriptions")
        # Migrate languages from additional_titles
        migrate_language("additional_titles")

        record.commit()

    for record_metadata in RDMRecord.model_cls.query.all():
        record = RDMRecord(record_metadata.data, model=record_metadata)

        remove_duplicate_languages(record)

        # Updating to new $schema when eventually saved
        record.pop("$schema", None)

        # Adding empty pids
        if record.pids is None:
            record.pids = {}

        record.commit()

    for draft_metadata in RDMDraft.model_cls.query.all():
        # Skipping deleted drafts because can't be committed
        if draft_metadata.is_deleted:
            continue

        draft = RDMDraft(draft_metadata.data, model=draft_metadata)

        remove_duplicate_languages(draft)

        # Updating to new $schema when eventually saved
        draft.pop("$schema", None)

        # Adding empty pids
        if draft.pids is None:
            draft.pids = {}

        draft.commit()

    db.session.commit()

    # Need to loop again to update the resource type once the scheme is updated
    for record_metadata in RDMRecord.model_cls.query.all():
        record = RDMRecord(record_metadata.data, model=record_metadata)

        update_vocabularies(record)

    for draft_metadata in RDMDraft.model_cls.query.all():
        # Skipping deleted drafts because can't be committed
        if draft_metadata.is_deleted:
            continue

        draft = RDMDraft(draft_metadata.data, model=draft_metadata)

        update_vocabularies(draft)

    for parent_metadata in RDMParent.model_cls.query.all():
        parent = RDMParent(parent_metadata.data, model=parent_metadata)

        # Updating to new $schema when eventually saved
        parent.pop("$schema", None)

        parent.commit()

    db.session.commit()
Example #2
0
def execute_upgrade():
    """Execute the upgrade from InvenioRDM 2.0 to 3.0.

    Please read the disclaimer on this module before thinking about executing
    this function!
    """
    for record_metadata in RDMRecord.model_cls.query.all():
        record = RDMRecord(record_metadata.data, model=record_metadata)

        # Updating to new $schema when eventually saved
        record.pop("$schema", None)

        # Adding empty pids
        if record.pids is None:
            record.pids = {}

        record.commit()

    for draft_metadata in RDMDraft.model_cls.query.all():
        # Skipping deleted drafts because can't be committed
        if draft_metadata.is_deleted:
            continue

        draft = RDMDraft(draft_metadata.data, model=draft_metadata)

        # Updating to new $schema when eventually saved
        draft.pop("$schema", None)

        # Adding empty pids
        if draft.pids is None:
            draft.pids = {}

        draft.commit()

    for parent_metadata in RDMParent.model_cls.query.all():
        parent = RDMParent(parent_metadata.data, model=parent_metadata)

        # Updating to new $schema when eventually saved
        parent.pop("$schema", None)

        parent.commit()

    # Cleanup associated deleted drafts.

    drafts = RDMDraftMetadata.query.filter(
        RDMDraftMetadata.is_deleted == True).all()  # noqa
    for d in drafts:
        # Delete all file draft records
        RDMFileDraftMetadata.query.filter_by(record_id=d.id).delete()

        # Bucket deletion
        bucket = d.bucket
        d.bucket = None
        d.bucket_id = None

        # Object and bucket not be removed if it's also associated with the
        # record.
        r = RDMRecordMetadata.query.filter_by(id=d.id).one_or_none()
        if r is None or r.bucket_id != bucket.id:
            bucket.remove()

    db.session.commit()