define()#
relationalai.Type
#Type.define(self, **kwargs: Tuple[Type, str, str]) -> None
Define properties for a type based on relationships with other types.
Parameters#
Name | Type | Description |
---|---|---|
*kwargs | tuple | Keyword arguments where keys are the names of the new properties and values are tuples of the form (Type, str, str) . Each value tuple must contain:
|
Returns#
None
.
Example#
Use Type.define()
to create new properties for a type based on relationships with other types:
#import relationalai as rai
model = rai.Model("people")
# Create a Person type from a table named 'people' in the 'sandbox.public'
# Snowflake schema. The table has a 'city_id' column that references the 'id'
# column of a table named 'cities'.
Person = model.Type("Person", source="sandbox.public.people")
# Create a City type from a table named 'cities' in the 'sandbox.public'
# Snowflake schema.
City = model.Type("City", source="sandbox.public.cities")
# Define a property named 'city' for the Person type that connects
# Person objects to City objects based on their 'city_id' property.
Person.define(city=(City, "city_id", "id"))
# Who lives in New York?
with model.query() as select:
# Get all Person objects.
person = Person()
# Filter for people who live in New York.
# Use the 'city' property to access the City object for each Person.
person.city.name == "New York"
response = select(person.name)
print(response.results)
# Output:
# name
# 0 Alice
If people may be associated with multiple cities,
use the .has_many()
method to declare that the property defined by .define()
is multi-valued:
#import relationalai as rai
model = rai.Model("people")
# Create a Person type from a table named 'people' in the 'sandbox.public'
# Snowflake schema. The table has a 'city_id' column that references the 'id'
# column of a table named 'cities'. There may be multiple rows for each person
# in the 'people' table, each with a different 'city_id'.
Person = model.Type("Person", source="sandbox.public.people")
City = model.Type("City", source="sandbox.public.cities")
# Define a multi-valued property named 'cities' for the Person type that
# connects Person objects to City objects based on their 'city_id' property.
Person.define(cities=(City, "city_id", "id"))
Person.cities.has_many()
# What cities are associated with the person named "Alice"?
with model.query() as select:
person = Person(name="Alice")
response = select(person.cities.name)
print(response.results)
# Output:
# name
# 0 New York
# 1 Boston
.define()
is primarily used on types derived from Snowflake tables or views,
where relationships between types are indicated by foreign key constraints.
However, you may use .define()
on any type:
#import relationalai as rai
model = rai.Model("people")
# Create Person and City types. Here, we don't specify Snowflake
# source tables, and will instead add objects directly to the types.
Person = model.Type("Person")
City = model.Type("City")
# Define a property named 'city' for the Person type that connects
# Person objects to City objects based on their 'city_id' property.
Person.define(city=(City, "city_id", "id"))
# Add some objects to the City type.
with model.rule():
City.add(id=1, name="New York")
City.add(id=2, name="San Francisco")
# Add some objects to the Person type.
with model.rule():
Person.add(id=1, name="Alice", city_id=1)
Person.add(id=2, name="Bob", city_id=2)
# Who lives in New York?
with model.query() as select:
# Get all Person objects.
person = Person()
# Filter for people who live in New York.
person.city.name == "New York"
response = select(person.name)
print(response.results)
# Output:
# name
# 0 Alice
In the preceding example, .define()
is unnecessary, since you can set objects as property values.
In fact, the model may be written much more concisely:
#model = rai.Model("people")
Person = model.Type("Person")
City = model.Type("City")
with model.rule():
Person.add(id=1, name="Alice", city=City.add(id=1, name="New York"))
Person.add(id=2, name="Bob", city=City.add(id=2, name="San Francisco"))