Skip to content

key errors in schemas when parsing XER files from non-oracle scheduling softwares #15

@ridgejo

Description

@ridgejo

There are a lot of other scheduling softwares now that allow exports in XER format (e.g. Phoenix, Elecosoft, etc) but often those XERs are "incomplete" in terms of the metadata that the file might contain as exported from Oracle, despite the core of the data being there. This leads to key errors in some of the schemas when using this library where they attempt to access the keys directly (despite the fields being marked optional).

In the example here below in the project schema the project completion date is marked with optional with the assumption the key exists with an empty value but fails because in these third party XER exports the key is missing. Fix is to change from directly accessing the key to using .get() with default value

`def init(
self,
sched_options: SCHEDOPTIONS,
default_calendar: CALENDAR | None = None,
**data: str,
) -> None:
self.options: SCHEDOPTIONS = sched_options

    # table fields from .xer file
    self.uid: str = data["proj_id"]
    """Unique Table ID"""
    self.add_date: datetime = datetime.strptime(data["add_date"], date_format)
    """Date Project was Created"""
    self.default_calendar: CALENDAR | None = default_calendar
    """Default Calendar Assigned to Project"""
    self.data_date: datetime = max(
        datetime.strptime(data["last_recalc_date"], date_format),
        datetime.strptime(data["plan_start_date"], date_format),
    )
    """Date Project is Updated To"""
    self.export_flag: bool = data["export_flag"] == "Y"
    """Project Export Flag"""
    self.finish_date: datetime = datetime.strptime(
        data["scd_end_date"], date_format
    )
    """Projected Completion Date"""
    self.last_fin_dates_id: str | None = optional_str(data["last_fin_dates_id"])
    """Last Stored Financial Period"""
    self.last_schedule_date: datetime | None = optional_date(
        data.get("last_schedule_date", "")
    )
    """Last Date Schedule was Calculated"""
    self.must_finish_date: datetime | None = optional_date(data["plan_end_date"])
    """Must Finish by Date Assigned to Project"""
    self.plan_start_date: datetime = datetime.strptime(
        data["plan_start_date"], date_format
    )
    """Planned Start Date Assigned to Project"""
    self.short_name: str = data["proj_short_name"]
    """Project Code"""

    # manually set from other tables
    self.activity_codes: list[ACTVTYPE] = []
    """Project Level Activity Codes"""
    self.calendars: list[CALENDAR] = []
    """Project Calendars"""
    self.project_codes: dict[PCATTYPE, PCATVAL] = {}
    """Project Codes Assigned to Project"""
    self.tasks: list[TASK] = []
    """Project Activities"""
    self.relationships: list[TASKPRED] = []
    """Project Relationships"""
    self.resources: list[TASKRSRC] = []
    """Activity Resources"""
    self.wbs_nodes: list[PROJWBS] = []
    """Project Work Breakdown Structure"""
    # self.wbs_root: PROJWBS | None = None
    self.user_defined_fields: dict[UDFTYPE, Any] = {}

`

So in the above would need to change
self.last_fin_dates_id: str | None = optional_str(data["last_fin_dates_id"])
to
self.last_fin_dates_id: str | None = optional_str(data.get("last_fin_dates_id", ""))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions