-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Best way to model groups of optional fields? #300
Comments
Here is a cookbook describing how to express logical relationships between fields.
We still need to provide some documentation about this, but at a high level, there are two approaches that I can think of. The first is to define all possible fields of all child types in the base type. Combining this with expressing logical relationships, we have an approach where we model all of the constraints for the fields in one base type, and then the derived types can specify either that a field doesn't appear (using
The second approach is to define a base type with only the common fields. Derived types then name the fields that they inherit from the base type, and include definitions for their own types. Here's what it looks like, applied to your example (using ISL 2.0, but translate-able to ISL 1.0).
The real difference between these two is whether the base type has closed fields or the child types close their fields. |
Both of these are a little verbose. We do have an open issue to improve this amazon-ion/ion-schema#113. If the proposed solution here is adopted, then it would become much simpler. You can define open base types, and then compose them into closed child types.
Feel free to leave feedback over on amazon-ion/ion-schema#113 if you have any opinions about it. |
Ah, yes, amazon-ion/ion-schema#113 looks promising, I guess I was just searching the wrong repo so I didn't find it. |
This is a somewhat contrived example, but it's simple enough to illustrate the issue without divulging any private details of the real thing I'm dealing with.
Imagine I have a list of structs representing times when an event happened, all of which must always contain a valid (year, month, day), and some of which also include additional resolution (hour, minute, second). I want to assert that if any of these additional fields are included, then all of them are, and all of them are valid.
(this is probably not the best way of modeling things, but in my case I'm trying to retrofit an ISL to describe the schema of an existing data format, so I'm not completely at liberty to change it).
{year: 2023, month: 12, day: 21}
{year: 2023, month: 12, day: 21, hour: 13, minute: 50, second: 00}
{year: 2023, month: 12, day: 21, hour: 13}
{year: 2023, month: 12, day: 21, hour: "oops", minute: "oops", second: "oops"}
One naive way I might try to model this as ISL:
In the above schema, the "Invalid" cases I listed above are considered valid
EventTime
, becauseone_of
matchesDate
, which is not a closed struct. But if I changeDate
to havefields: closed::{ ... }
, then theall_of
inEventTime
can never be satisfied. This is similarly the case if I rework the schema to have aDateTime
which hastype: Date
and adds the fields fromTime
(AFAIK, you can't inherit from a closed-struct and add more fields to it).So far the only solution I've been able to come up with is to duplicate the definitions of the
year
,month
, andday
fields fromDate
into a secondDateTime
type, mark bothDate
andDateTime
asclosed::{...}
, and makeEventTime
beone_of: [Date, DateTime]
, but this is mildly annoying because I have to remember to keep the field definitions ofDate
andDateTime
in sync.I would describe the use case generally as one of these two:
Is there an intended way to describe this in ISL?
The text was updated successfully, but these errors were encountered: