-
Notifications
You must be signed in to change notification settings - Fork 111
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
What's the best way to compare periods? #17
Comments
@mmabey first of all thank you much for your help to improve the strength of this package. However, I can explain about Date, dateTime of FHIR.
What about business requirements like yours?This library uses pydantic's validator strength to allow custom root validator for each model. I cannot make full documentation yet. But here example code
this function should be called |
This is a very interesting feature of pydantic, thanks for sharing! If I'm understanding your example correctly, the modified from my_fhir_shim import Period Is this ☝️ correct? If so, I'm not sure it helps me. For all of the FHIR objects I construct, I don't know beforehand what resource type I'm creating, so I'm making heavy use of the In any case, I'm not creating |
I think you are almost got it, I am trying to minimize some misunderstanding. I am taking your example, the file name is
|
That makes so much more sense. Thank you for clarifying! It looks like it will be a while before I'm able to make another attempt at using a root validator in my project. I'll reopen if I'm unable to figure it out. Thanks again! |
For anyone that finds this thread because they want to know how to add a root validator to a pydantic model without touching the model itself, there's one critical thing that was missing from @nazrulworld's example above. The validator function must from typing import Dict
from fhir.resources.DSTU2.period import Period
from .parse_helpers import parse_end_time, parse_start_time
def normalize_period_dates(cls, values: Dict):
if not values:
return values
raw_start = values.get("start")
raw_end = values.get("end")
if raw_start:
values["start"] = parse_start_time(raw_start)
if raw_end:
values["end"] = parse_end_time(raw_end)
return values
class Shims:
_done = None
@classmethod
def setup_shims(cls):
if Shims._done:
return
# Add all root validators here
Period.add_root_validator(normalize_period_dates, pre=True)
Shims._done = True
Shims.setup_shims() |
I've been taking a look at the pydantic refactored code, and I think it's going to be a great thing for the project. As I've looked at how to adapt my code to the changes, one thing has come up that I can't quite find a good answer for.
In the project I'm working on, there are lots of instances where I need to be able to compare one Period with another. For example, I need to know which period is more recent than another. This gets really tricky because FHIR's dateTime values have such a wide range of acceptable granularity. For example, I might need to decide if a period with a starting year, month, and day is more recent than a period with an ending year and month (but no day).
The solution I came up with previously was to not depend on the Python
datetime
objects offered by the previous (<=5.0.1) versions offhir.resources
, but instead parse the FHIR start and enddateTime
values myself and slightly differently, with start dates filling any missing values for month, day, hour, minute, second, and microsecond with the lowest (earliest) value (e.g., month=1, hour=0, etc). Likewise, I parsed enddateTime
values by filling any missing values with the highest (latest) value possible (e.g., month=12, minute=59).The above solution depended on using the
origval
property of thefhir.resources.period.Period
object, which I used as input to the custom parsers I just described. And this is where the problem arises: The new pydantic models do not retain the original string extracted from the FHIR-formatted JSON.I've tried to do some research into possible ways to address this, but due to my lack of familiarity with the ins and outs of pydantic, I've probably missed some viable solutions. Anyway, here are some ideas:
Alter the pydantic models for
Date
,DateTime
,Instant
, andTime
to make the original string value available (the ones defined infhir/resources/{DSTU2,STU3,}/fhirtypes.py
. I list this first because I think it will be the least labor-intensive, assuming there's a way to actually accomplish this with pydantic. From what I understand, these model types would need to use generic classesvalidate
methods instead of the classes from thedatetime
library. This is only a half-con though since I think the pydantic docs recommend doing it that way anyway.Create a custom class for Periods that allow for fuzzy data (according to the FHIR spec) while also providing operators that allow for comparison in a way that makes sense (I drew up a few examples of this but eventually decided they were confusing).
That's all I've got so far. I'm hoping that by discussing this we can find something that will be useful to many of the library's users.
The text was updated successfully, but these errors were encountered: