Skip to content

Latest commit

 

History

History
95 lines (68 loc) · 2.58 KB

has-one.mdx

File metadata and controls

95 lines (68 loc) · 2.58 KB
title description
Has One
Define one-to-one relationships between feature classes.

import { PyDiffEditor } from '@/components/Editor' import { highlightedCode as oneToOneDiff } from '@/samples/features/one_to_one.py?highlight=diff-py' import { highlightedCode as hasOneOptionalDiff } from '@/samples/features/one_to_one_optional.py?highlight=diff-py' import { TipInfo } from '@/components/Tip'


Has-one relationships link a feature to a single instance of another feature.

Recommended Implementation

The simplest way to specify a join for a has-one relationship is implicitly. In the example below, a User is linked to their Profile.

from chalk.features import features

@features
class Profile:
    id: str
    user_id: "User.id"
    email_age_years: float

@features
class User:
    id: str
    profile: Profile

With a has-one relationship established, you can reference features on Profile through User. For example:

user_email_age = User.profile.email_age_years

Explicit Join

In the following snippet, the has-one join is explicitly defined. This is functionally equivalent to the recommended implementation:

from chalk.features import features, has_one, ...

@features
class Profile:
    id: str
    user_id: str
    email_age_years: float

@features
class User:
    id: str
    uid: str
    profile: Profile = has_one(lambda: Profile.user_id == User.uid)
The lambda solves forward references, letting you reference User before it is defined.

Back-references

One-to-one

You can also add a back-reference to User from Profile. However, you don't have to explicitly set the join on Profile. Instead, the join condition is assumed to be symmetric and copied over. To complete the one-to-one relationship from our example, add a User to the Profile class:

Here you need to use quotes around User to use a forward reference.

Optional relationships

When a has-one relationship is specified, the default behavior is to treat the linked Feature as required. Following the example above, specifying a User without a Profile and querying for a User's profile or using the User.profile in a resolver raises an error.

To define optional relationships, use the typing.Optional[...] keyword:

Note, resolvers that take optional features as inputs need to handle the None case. This is covered in more detail in the resolver's section of the docs.