relationalai.dsl.Model
class Model( name: str, *, config: Config | None = None, format: str = "default", profile: str | None = None, connection: SnowflakeConnection | None = None, ensure_change_tracking: bool = False)
A RelationalAI model is made up of objects,
which represent real-world entities and are categorized by type,
and rules that describe objects and the relationships between them.
The Model
class is used to create, manage, and query models.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
name | str | The name of the model. Must be at least three characters. May only contain letters, numbers, and underscores. |
config | Config or None | Optional configuration object to use when creating the model. If None , configuration is read from your raiconfig.toml file. See the Configuration guide for more information on configuring models. |
format | str | Optional format for query responses. Default is "default" , which stores results as a pandas DataFrame. Use "snowpark" to get results as a Snowpark DataFrame. |
profile | str or None | Optional name of the configuration profile to use when creating the model. If None , the currently active profile is used. |
connection | Session or None | Optional Snowpark Session object to use when creating the model. If None , connection details in the configuration profile set by the profile parameter are used. Ignored in Azure-based projects. |
ensure_change_tracking | bool | Optional flag to enable change tracking on tables or views passed to the source parameter. (Default: False ). |
Example
Section titled “Example”import relationalai as rai
# Create a new model named "people."model = rai.Model("people")
# Get the Person table from the 'sandbox.public' schema in Snowflake.Person = model.Type("Person", source="sandbox.public.person")
# Create an Adult type in the model.Adult = model.Type("Adult")
# The model.rule() context manager is used to define rules in the model.# This rule adds all people over 18 to the Adult type.with model.rule(): person = Person() person.age >= 18 person.set(Adult)
# The model.query() context manager is used to query the model.# This query returns the names of all adults in the model.with model.query() as select: adult = Adult() response = select(adult.name)
print(response.results)# Output:# name# 0 Alice# 1 Bob
By default, query results are returned as a pandas DataFrame,
which downloads to your local machine and can be slow down large datasets.
To keep results in Snowflake and avoid downloads, use format="snowpark"
when creating the model:
# NOTE: The format parameter must be passed as a keyword argument.model = rai.Model("people", format="snowpark")
# ...
with model.query() as select: adult = Adult() response = select(adult.name)
# The response is a Snowpark DataFrame.print(response.results)# Output:# <snowflake.snowpark.dataframe.DataFrame object at 0x1313d3590>
# To view the contents of the Snowpark DataFrame, use the .show() method.response.results.show()# Output:# ----------# |"NAME" |# ----------# |Bob |# |Alice |# ----------
# To save results to a table in Snowflake, use the .write() method.response.results.write.save_as_table("sandbox.public.adults")
Refer the Snowflake documentation for details on working with Snowpark DataFrames.
You may also export a Python function as a Snowflake stored procedure using the .export()
method,
allowing Snowflake SQL users to interact with the model:
# Export a function to the `sandbox.public` schema in Snowflake.# The stored procedure is named "get_adults_by_age".# NOTE: Type hints are required for the function parameters and return values.
from typing import Tuple
@model.export("sandbox.public")def get_adults_by_age(age: int) -> Tuple[str, int]: adult = Adult(age=age) return adult.name, adult.age
# The stored procedure can be called in Snowflake SQL:# CALL sandbox.public.get_adults_by_age(21);
Anything you can do in a query context can be done in an exported function, including advanced logic and graph reasoning.
See .export()
for more details.
To use a configuration profile other than the active profile,
pass the profile name to the profile
parameter when creating the model:
# NOTE: The profile name must be passed as a keyword argument.model = rai.Model("people", profile="my_profile")
To use a Snowpark Session other than the one specified in the configuration profile,
pass a Session
object to the connection
parameter when creating the model:
from snowflake.snowpark import Session
connection_parameters = { "user": <USER>, "password": <PASSWORD>, "account": <ACCOUNT>, "warehouse": <WAREHOUSE>, "database": <DATABASE>, "schema": <SCHEMA>)
conn = Session.builder.configs(connection_parameters).create()
# NOTE: The connection object must be passed as a keyword argument.model = rai.Model("people", connection=conn)
See the Snowflake docs for more details on creating Snowpark Session objects.
Attributes
Section titled “Attributes”Name | Type | Description |
---|---|---|
.name | str | The name of the model. |
Returns a string containing the name of the model:
import relational as rai
model = rai.model("myModel")
print(model.name)# Output:# 'myModel'
Methods
Section titled “Methods”Name | Description | Returns |
---|---|---|
.Type() | Creates a Type for categorizing objects in the model. | Type |
.rule() | Adds a rule to the model. | Context |
.query() | Queries the model. | Context |
.export() | Exports a Python function as a Snowflake stored procedure. Used as a decorator. | Callable |
.rule()
and .query()
are Python context managers
and must be used in a with
statement.
The with
block defines the scope of the rule or query
and is where you define the rule or query logic using the RelationalAI query-builder syntax.
The following methods create contexts for expressing conditional logic in rules and queries
and must be called from inside a .rule()
or .query()
context’s with
block:
Name | Description | Returns |
---|---|---|
.found() | Checks that a subquery has at least one result. | Context |
.not_found() | Checks that a subquery has no results. | Context |
.match() | Matches objects to one or more subqueries. Similar to a Python match or a SQL CASE statment. | Context |
.case() | Creates a subquery inside of a .match() context. | Context |
.case()
Section titled “.case()”Model.case(dynamic: bool = False) -> Context
Creates a subquery context in .match()
contexts with a conditional scope.
Must be used in a rule or query context.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
dynamic | bool | Whether or not the context is dynamic. Dynamic queries support Python control flow as macros. See Context for more information. |
Returns
Section titled “Returns”A Context
object.
Example
Section titled “Example”Use Model.case()
to add subqueries to a .match()
context.
.case()
is a context manager
and must be called in a with
statement:
import relationalai as rai
# Create a model named "people" with Person, Adult, and Senior types.model = rai.Model("people")Person = model.Type("Person")Adult = model.Type("Adult")Senior = model.Type("Senior")
# Add some people to the model.with model.rule(): jack = Person(name="Jack", age=15) joe = Person(name="Joe", age=30) jane = Person(name="Jane", age=65)
# Assign people to the Adult and Senior types based on age.with model.rule(): # Get all Person objects. person = Person() with model.match(): with model.case(): # Check if the person is at least 60 years old. person.age >= 60 person.set(Senior) with model.case(): # Check if the person is at least 18 years old. person.age >= 18 person.set(Adult)
# Who is a Senior?with model.query() as select: dog_owner = DogOwner() response = select(dog_owner.name)
print(response.results)# Output:# name# 0 Jane
# Who is an Adult?with model.query() as select: adult = Adult() response = select(adult.name)
print(response.results)# Output:# name# 0 Joe
You may write the above rule more compactly by using person.age >= 60
and person.age >= 18
as context managers:
with model.rule() person = Person() with model.match(): with person.age >= 60: person.set(Senior) with person.age >= 18: person.set(Adult)
Use .case()
to add a default case to a .match()
context when no other cases match:
Child = model.Type("Child")with model.match(): with person.age >= 60: person.set(Senior) with person.age >= 18: person.set(Adult) with model.case(): person.set(Child)
# Who is a Child?with model.query() as select: child = Child() response = select(child.name)
print(response.results)# Output:# name# 0 Jack
.export()
Section titled “.export()”Model.export(schema: str) -> Callable
Exports a Python function as a Snowflake stored procedure.
Must be used as a decorator for the function to be exported.
If the schema
string contains only a database and schema, i.e. my_db.my_schema
, the stored procedure is created in the specified schema with the same name as the decorated function.
If the schema
string contains a fully-qualified name, i.e. my_db.my_schema.my_stored_procedure
, the stored procedure is created in the specified schema with the specified name.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
schema | str | May be either:
|
Returns
Section titled “Returns”A Callable
object representing the decorated function.
Note, however, that the returned function cannot be used directly in Python.
Only the stored procedure created in Snowflake may be called.
Example
Section titled “Example”Use export()
to export a Python function as a Snowflake stored procedure.
The contents of the decorated function must be written in the RelationalAI query-builder syntax.
You can think of the function as containing the contents of a Model.query()
block with the select()
function replaced by a return
statement.
There are two types of stored procedures that can be created using export()
:
-
Create a stored procedure that returns a table.
Provide type hints for both function parameters and return values to export a stored procedure that returns a table of results:
import relationalai as rai# Create a model named "MyModel".model = rai.Model("MyModel")# Create a Person type.Person = model.Type("Person")# Add some people to the model.with model.rule():alice = Person.add(id=1).set(name="Alice", age=21)bob = Person.add(id=2).set(name="Bob", age=22)carol = Person.add(id=3).set(name="Carol", age=23)# Create a friends property and assign some friends to each person.alice.friends.extend([bob, carol])bob.friends.extend([alice])carol.friends.extend([alice])# Define a function to export as a stored procedure. Type hints for function# parameters are required. When type hints are provided, as in this example,# the resulting stored procedure returns a table of results.@model.export("sandbox.public")def get_friends_of_person(id: int) -> int:person = Person()person.id == idreturn person.friends.id# The stored procedure can now be called in Snowflake SQL:rai.Provider().sql("CALL sandbox.public.get_friends_of_person(1);") -
Create a stored procedure that saves results to a table.
If the decorated function only has type hints for its parameters and no return type hint, the resulting stored procedure will write results to a specified table. The table name must be provided when the stored procedure is called in Snowflake SQL:
import relationalai as rai# Create a model named "MyModel".model = rai.Model("MyModel")# Create a Person type.Person = model.Type("Person")# Add some people to the model.with model.rule():alice = Person.add(id=1).set(name="Alice", age=21)bob = Person.add(id=2).set(name="Bob", age=22)carol = Person.add(id=3).set(name="Carol", age=23)# Create a friends property and assign some friends to each person.alice.friends.extend([bob, carol])bob.friends.extend([alice])carol.friends.extend([alice])# Define a function to export as a stored procedure. Type hints for function# parameters are required. When no return type hint is provided, the resulting# stored procedure writes results to a specified table.@model.export("sandbox.public")def get_friends_of_person(id: int):person = Person()person.id == idreturn person.friends.id, person.friends.name# The stored procedure can now be called in Snowflake SQL. Note that the# fully-qualified name of the table where the results will be saved must# be provided as an argument.rai.Provider().sql("CALL sandbox.public.get_friends_of_person(1, 'sandbox.public.friends_of_alice');")# The result table can then be queried in Snowflake SQL.rai.Provider().sql("SELECT * FROM sandbox.public.friends_of_alice;")
Supported Type Hints
Section titled “Supported Type Hints”For both types of stored procedures, the decorated functions type hints must be on of the following supported types:
Python Type | Description | Corresponding Snowflake Type |
---|---|---|
relationalai.Type | A RelationalAI entity hash | NUMBER |
str | A string | VARCHAR |
int | An integer | NUMBER |
float | A floating-point number | NUMBER |
decimal.Decimal | A decimal number | NUMBER |
numbers.Number | Equivalent to decimal.Decimal | NUMBER |
datetime.datetime | A datetime | TIMESTAMP |
datetime.date | A date | DATE |
bool | A boolean | BOOLEAN |
Exported Stored Procedure Signature
Section titled “Exported Stored Procedure Signature”The signature of the stored procedure created by export()
is determined by the type hints of the decorated function and whether or not return type hints are provided:
-
With return type hints: If the decorated function has return type hints, the stored procedure signature is the same as the return type hints of the function, with an additional optional
ENGINE
parameter for specifying a specific RAI engine to use when executing the stored procedure.For example, the
get_friends_of_person
function in the first example above has a return type hint ofint
, so the stored procedure signature is:CREATE OR REPLACE PROCEDURE sandbox.public.get_friends_of_person(id INT, ENGINE VARCHAR)RETURNS TABLE (id INT) -
Without return type hints: If the decorated function does not have return type hints, the stored procedure signature is the same as the function’s parameter type hints, with two additional parameters:
- A required
SAVE_AS_TABLE
parameter for specifying the fully-qualified name of the table where the results will be saved. - An optional
ENGINE
parameter for specifying a specific RAI engine to use when executing the stored procedure.
For example, the
get_friends_of_person
function in the second example above does not have a return type hint, so the stored procedure signature is:CREATE OR REPLACE PROCEDURE sandbox.public.get_friends_of_person(id INT, SAVE_AS_TABLE VARCHAR, ENGINE VARCHAR)RETURNS VARCHAR - A required
For more details on Snowflake stored procedures, refer to the Snowflake documentation.
Engine Selection
Section titled “Engine Selection”Stored procedures created using export()
contain a copy of the query generated by the decorated function.
When the stored procedure is called in Snowflake SQL, the query is executed using a RelationalAI engine.
Which engine is used to execute the query is determined in the following order:
- The engine passed to the procedures
ENGINE
parameter, if present. - The first available engine created by the user calling the stored procedure, if there are any.
- The engine specified in the user’s config at export time.
.found()
Section titled “.found()”Model.found(dynamic: bool = False) -> Context
Filters objects to only those that satisfy the conditions in the .found()
context.
Must be used in a rule or query context.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
dynamic | bool | Whether or not the context is dynamic. Dynamic queries support Python control flow as macros. See Context for more information. |
Returns
Section titled “Returns”A Context
object.
Example
Section titled “Example”Model.found()
is a context manager
and should be called in a with
statement.
It must be called from within a rule or query context:
import relationalai as rai
model = rai.Model("people")Person = model.Type("Person")
with model.rule(): Person.add(name="Fred", age=22) Person.add(name="Janet", age=63)
# `model.found()` is always called in a nested `with` block# inside of a `model.rule()` or `model.query()` context.with model.query() as select: person = Person() with model.found(): person.age > 60 response = select(person.name)
print(response.results)# Output:# name# 0 Janet
In the preceding example, model.found()
restricts the person
instance to objects with an age
value greater than 60.
But it does so without exposing the person.age
producer to the surrounding context.
In other words, the restriction of person.age
to values greater than 60 only applies inside of the model.found()
sub-context.
This is especially important to remember when objects have a property with multiple values:
import relationalai as rai
model = rai.Model("people")Person = model.Type("Person")Dog = model.Type("Dog")Bird = model.Type("Bird")
# Add people and pets to the model.with model.rule(): fred = Person.add(name="Fred", age=22) janet = Person.add(name="Janet", age=63) mr_beaks = Bird.add(name="Mr. Beaks") spot = Dog.add(name="Spot") buddy = Dog.add(name="Buddy") # Fred has one pet and Janet has two. fred.set(pet=buddy) janet.set(pet=spot).set(pet=mr_beaks)
# What are the names of all pets of bird owners?with model.query() as select: person = Person() # Restrict `person` to objects with a `pet` property # set to an object in the `Bird` type. with model.found(): person.pet == Bird() response = select(person.name, person.pet.name)
print(response.results)# Output:# name name2# 0 Janet Mr. Beaks# 1 Janet Spot
Janet is the only person in the results because she is the only person with a pet bird.
Both of her pets, Spot and Mr. Beaks, appear in the results because the restriction
of person.pet
to the Bird
type only applies inside the with model.found()
block.
Contrast that to the following query:
with model.query() as select: person = Person() person.pet == Bird() response = select(person.name, person.pet.name)
print(response.results)# Output:# name name2# 0 Janet Mr. Beaks
Only Mr. Beaks appears because person.pet == Bird()
restricts person.pet
to the Bird
type.
.match()
Section titled “.match()”Model.match(multiple: bool = False, dynamic: bool = True) -> Context
Matches objects to one or more subqueries.
Similar to a Python match
or a SQL CASE
statement.
Must be used in a rule or query context.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
multiple | bool | Whether or not the context matches multiple queries. If True , objects match all subqueries that filter them. If False , objects match only the first. |
dynamic | bool | Whether or not the context is dynamic. Dynamic queries support Python control flow as macros. See Context for more information. |
Returns
Section titled “Returns”A Context
object.
Example
Section titled “Example”Model.match()
is a
context manager
and should be called in a with
statement.
It must be called from within a rule or query context:
import relationalai as rai
model = rai.Model("students")Student = model.Type("Student")
with model.rule(): Student.add(name="Fred", grade=87) Student.add(name="Johnny", grade=65) Student.add(name="Mary", grade=98)
with model.rule(): student = Student() with model.match(): # Match students to subqueries based on their grade. with student.grade >= 90: student.set(letter_grade="A") with student.grade >= 80: student.set(letter_grade="B") with student.grade >= 70: student.set(letter_grade="C") # Default case when no other conditions are met. with model.case(): student.set(letter_grade="F")
# Which students got a B?with model.query() as select: student = Student(letter_grade="B") response = select(student.name, student.grade, student.letter_grade)
print(response.results)# Output:# name grade letter_grade# 0 Fred 87 B
You can think of consecutive with
statements inside of a Model.match()
context as branches of an if
-else
statement.
In the example above, the letter_grade
property of student
objects is set based on their grade
property.
Only the first matching with
statement is applied to each object.
To match multiple subqueries, set the multiple
parameter to True
:
with model.rule(): student = Student() with model.match(multiple=True): with student.grade >= 90: student.set(letter_grade="A") with student.grade >= 80: student.set(letter_grade="B") with student.grade >= 70: student.set(letter_grade="C") with model.case(): student.set(letter_grade="F")
# Which students got a B?with model.query() as select: student = Student(letter_grade="B") response = select(student.name, student.grade, student.letter_grade)
print(response.results)# Output:# name grade letter_grade# 0 Fred 87 B# 1 Mary 98 B
Mary has .letter_grade
set to "B"
.
She also has .letter_grade
set to "A"
and "C"
because her grade meets the conditions
in the first three of the four with
statements.
Set dynamic
to True
to use Python control flow inside of the .match()
context.
This allows you to leverage Python as a macro language to generate subqueries dynamically:
with model.rule(): student = Student() with model.match(dynamic=True): for grade, letter in [(90, "A"), (80, "B"), (70, "C")]: with student.grade >= grade: student.set(letter_grade=letter) with model.case(): student.set(letter_grade="F")
.match().__enter__()
returns an optional ContextSelect
object
that may be used to group objects matched by the context for further manipulation.
For instance, the following example calculates student letter grades in a query,
not a rule, and filters students who got a B:
# Which students got a B?# This time, we're calculating the letter grade in a query, not a rule.with model.query() as select: student = Student() with model.match(dynamic=True) as matched: for grade, letter in [(90, "A"), (80, "B"), (70, "C")]: with student.grade >= grade: matched.add(student, letter_grade=letter) with model.case(): matched.add(student, letter_grade="F") # Filter students who got a B. matched.letter_grade == "B" response = select(students.name, students.grade, students.letter_grade)
print(response.results)# Output:# name grade v# 0 Fred 87 B
You can only use with
statements directly under a Model.match()
block:
# INCORRECTwith model.rule(): with model.match(): student = Student() # Raises an error with student.grade >= 90: student.set(letter_grade="A") # ...
# CORRECTwith model.rule(): student = Student() with model.match(): with student.grade >= 90: student.set(letter_grade="A") # ...
# - OR -
with model.rule(): with model.match(): with model.case(): student = Student() # OK because it's nested under a `with` statement student.grade >= 90 student.set(letter_grade="A") # ...
.not_found()
Section titled “.not_found()”Model.not_found(dynamic: bool = False) -> Context
Filters objects to only those that do not satisfy the conditions in the .not_found()
context.
Must be used in a rule or query context.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
dynamic | bool | Whether or not the context is dynamic. Dynamic queries support Python control flow as macros. See Context for more information. |
Returns
Section titled “Returns”A Context
object.
Example
Section titled “Example”Model.not_found()
is a context manager
and should be called in a with
statement.
It must be called from within a rule or query context:
import relationalai as rai
model = rai.Model("people")Person = model.Type("Person")
with model.rule(): Person.add(name="Fred", age=22) Person.add(name="Janet", age=63)
# `model.not_found()` is always called in a nested `with` block# inside of a `model.rule()` or `model.query()` context.with model.query() as select: person = Person() # Restrict `person` to objects that do not have # a `name` property set to the string `"Janet"`. with model.not_found(): person.name == "Janet" response = select(person.name)
print(response.results)# Output:# name# 0 Fred
.query()
Section titled “.query()”Model.query(dynamic: bool = False, format: str = "default") -> Context
Creates a query Context
.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
dynamic | bool | Whether or not the query is dynamic. Dynamic queries support Python control flow as macros. See Context for more information. |
format | str | Optional format for query responses. Default is "default" , which stores results as a pandas DataFrame. Use "snowpark" to get results as a Snowpark DataFrame. |
Returns
Section titled “Returns”A Context
object.
Example
Section titled “Example”Model.query()
is a context manager
and should be called in a with
statement.
Use the as
part of the with
statement to assign the ContextSelect
object
created by Model.query()
to a variable named select
so that you may select query results:
import relationalai as rai
model = rai.Model("people")Person = model.Type("Person")
# Add people to the model.with model.rule(): alex = Person.add(name="Alex", age=19) bob = Person.add(name="Bob", age=47) carol = Person.add(name="Carol", age=17)
# A `with model.query() as select` block begins a new query.# `select` is a `ContextSelect` object used to select query results.with model.query() as select: person = Person() response = select(person.name)
# Query results are stored in the `results` attribute of the response.# The `results` attribute is a pandas DataFrame by default.print(response.results)# Output:# name# 0 Alex# 1 Bob# 2 Carol
You write queries using RelationalAI’s declarative query builder syntax. Refer to the Executing Queries for an introdcution to writing queries.
By default, query results are returned as a pandas DataFrame,
which downloads to your local machine and can be slow down large datasets.
To keep results in Snowflake and avoid downloads, use format="snowpark"
when creating the query:
with model.query(format="snowpark") as select: person = Person() response = select(person.name)
# The response is a Snowpark DataFrame.print(response.results)# Output:# <snowflake.snowpark.dataframe.DataFrame object at 0x1313d3590>
# To view the contents of the Snowpark DataFrame, use the .show() method.response.results.show()# Output:# ----------# |"NAME" |# ----------# |Alex |# |Bob |# |Carol |# ----------
# To save results to a table in Snowflake, use the .write() method.response.results.write.save_as_table("sandbox.public.people")
Alternatively, you may set format="snowpark"
when creating the model to return Snowpark DataFrames by default for all queries:
# NOTE: The format parameter must be passed as a keyword argument.model = rai.Model("people", format="snowpark")
Refer to the Snowflake documentation for details on working with Snowpark DataFrames.
Note that you may pass data from your Python application into a query:
name_to_find = "Carol"property_to_find = "age"
with model.query() as select: person = Person(name=name_to_find) prop = getattr(person, property_to_find) response = select(prop)
print(response.results)# Output:# age# 0 17
Here, the Python variables name_to_find
and property_to_find
are used directly in the query.
Python’s built-in getattr()
function
gets the person
property with the name property_to_find
.
By default, queries do not support while
and for
loops and other flow control tools such as if
and
match
.
You can enable flow control by setting the dynamic
parameter to True
,
which lets you use Python flow control as a macro to build up a query dynamically:
# Application is being used by an external user.IS_INTERNAL_USER = FALSE
with model.query() as select: person = Person() if not IS_INTERNAL_USER: Public(person) response = select(person.name, person.age)
In this query, the application user’s state determines whether or not to include a condition.
If the user is external, only Public
objects are selected.
.rule()
Section titled “.rule()”Model.rule(dynamic: bool = False) -> Context
Creates a rule Context
.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
dynamic | bool | Whether or not the rule is dynamic. Dynamic queries support Python control flow as macros. See Context for more information. |
Returns
Section titled “Returns”A Context
object.
Example
Section titled “Example”Model.rule()
is a context manager
and should be called in a with
statement.
Rules describe objects in a model:
import relationalai as rai
model = rai.Model("people")Person = model.Type("Person")Adult = model.Type("Adult")
# Add people to the model.with model.rule(): alex = Person.add(name="Alex", age=19) bob = Person.add(name="Bob", age=47) carol = Person.add(name="Carol", age=17)
# All people that are 18 years old or older are adults.with model.rule() as select: person = Person() person.age >= 18 person.set(Adult)
You write rules using RelationalAI’s declarative query builder syntax. See Core Concepts for an introduction to writing rules and queries.
Note that you may pass data from your Python application into a rule:
min_adult_age = 21
with model.rule() as select: person = Person() person.age >= min_adult_age person.set(Adult)
By default, rules do not support while
and for
loops and other flow control tools such as if
and
match
.
You can enable flow control by setting the dynamic
parameter to True
,
which lets you use Python flow control as a macro to build up a rule dynamically:
with model.rule(dynamic=True): person = Person() for i in range(3): person.set(count=i)
.Type()
Section titled “.Type()”Model.Type(name: str, source: Optional[str] = None) -> Type
Declares a new Type in the model.
Use the optional source
parameter to specify a Snowflake table with source data for objects with the given type.
Rows in the table are used to create entities of the given type, and columns in the table are used to infer properties of the objects.
Parameters
Section titled “Parameters”Name | Type | Description |
---|---|---|
name | str | The name of the type. Must begin with a Unicode letter or an underscore followed by one or more Unicode letters, underscores, or numbers. |
source | str | (Optional) The name of a Snowflake table or view with source data for objects with the given type. (Default: None .) |
Returns
Section titled “Returns”A Type
object.
Supported Snowflake Data Types
Section titled “Supported Snowflake Data Types”The following Snowflake data types are supported in tables and views passed to the source
parameter:
Example
Section titled “Example”Use Model.Type()
to declare a new type in the model:
import relationalai as rai
model = rai.Model("MyModel")
# Declare a Person type.Person = model.Type("Person")
# Use the Person type to define Person objects.with model.rule(): Person.add(name="Alice") Person.add(name="Bob")
When you declare a type with the source
parameter, objects with that type are created using data from the specified Snowflake table.
Each row in the table corresponds to an object with the given type.
Properties of the objects are inferred from the columns in the table, using the lowercased column names as property names.
For instance, suppose you have a Snowflake table named people
with columns Name
and Age
with the following data:
Name | Age |
---|---|
Alice | 25 |
Bob | 30 |
In the following model, the Person
type is defined with source data from the people
table:
import relationalai as rai
model = rai.Model("MyModel")
# Declare a Person type with source data from a Snowflake table named "people".# <db> and <schema> are placeholders for the Snowflake database and schema names.Person = model.Type("Person", source="<db>.<schema>.people")
# Properties of Person objects are inferred from the columns in the "people" table# and are accessible as attributes of the Person type using lowercased column names.with model.query() as select: person = Person() response = select(person.name, person.age)
print(response.results)# name age# 0 Alice 25# 1 Bob 30