glam/schemas/20251121/linkml/scripts/migrate_remaining_slots.py

89 lines
3.5 KiB
Python

import os
import glob
import yaml
CLASSES_DIR = "schemas/20251121/linkml/modules/classes"
SLOTS_DIR = "schemas/20251121/linkml/modules/slots"
ARCHIVE_DIR = "schemas/20251121/linkml/archive/slots"
# Map old slot name to new slot name
REPLACEMENTS = {
"has_or_had_classification": "is_or_was_classified_as",
"has_or_had_comprehensive_overview": "has_or_had_overview",
"has_or_had_precision": "has_or_had_level",
"has_or_had_product_category": "sells_or_sold",
"has_or_had_registration_number": "has_or_had_identifier",
"has_or_had_related_archive": "is_or_was_related_to",
"has_or_had_related_guide": "is_or_was_related_to",
"has_or_had_research_attempt": "is_or_was_based_on",
"has_or_had_safeguard": "preserves_or_preserved",
"has_or_had_scene_segment": "contains_or_contained",
"has_or_had_secondary_system": "is_or_was_stored_in",
"has_or_had_section_link": "contains_or_contained",
"has_or_had_short_code": "has_or_had_code",
"has_or_had_silence_segment": "contains_or_contained",
"has_or_had_sound_event_type": "contains_or_contained",
"has_or_had_speech_segment": "contains_or_contained",
"has_or_had_storage_facility": "has_or_had_facility",
"has_or_had_strategic_objective": "has_or_had_objective",
"has_or_had_sub_guide": "contains_or_contained",
"has_or_had_sub_section": "contains_or_contained",
"has_or_had_text_region": "contains_or_contained",
"has_or_had_thematic_route": "has_or_had_convention",
"has_outdoor_seating": "has_or_had_service",
"has_publication_series": "publishes_or_published",
"has_research_library": "has_or_had_facility",
"has_security_system": "has_or_had_system",
"has_sub_branch": "has_or_had_branch",
"has_unit": "has_or_had_section",
"hazard": "has_or_had_risk",
"hc_id": "has_or_had_identifier",
"hc_preset_uri": "has_or_had_uri",
"heading_level": "contains_or_contained",
"heading_text": "contains_or_contained",
"heading_text_en": "contains_or_contained",
"headline": "has_or_had_title",
"heritage_designation_date": "is_or_was_designated_on"
}
def migrate_classes():
files = glob.glob(os.path.join(CLASSES_DIR, "*.yaml"))
for f in files:
with open(f, 'r') as file:
content = file.read()
original_content = content
for old, new in REPLACEMENTS.items():
if old in content:
# Naive replacement - be careful with partial matches?
# Most of these are distinct enough.
# has_or_had_related_guide -> is_or_was_related_to
content = content.replace(old, new)
if content != original_content:
print(f"Updating {f}")
with open(f, 'w') as file:
file.write(content)
def archive_slots():
if not os.path.exists(ARCHIVE_DIR):
os.makedirs(ARCHIVE_DIR)
for old in REPLACEMENTS.keys():
src = os.path.join(SLOTS_DIR, f"{old}.yaml")
if os.path.exists(src):
dst = os.path.join(ARCHIVE_DIR, f"{old}.yaml")
print(f"Archiving {src} to {dst}")
os.rename(src, dst)
# Also archive has_or_had_custodian_type which was already replaced
src = os.path.join(SLOTS_DIR, "has_or_had_custodian_type.yaml")
if os.path.exists(src):
dst = os.path.join(ARCHIVE_DIR, "has_or_had_custodian_type.yaml")
print(f"Archiving {src} to {dst}")
os.rename(src, dst)
if __name__ == "__main__":
migrate_classes()
archive_slots()