Skip to main content
Version: v3.x (DDN)

Models Read Data

Introduction

In DDN, models represent entities or collections that can be queried in your data sources, such as tables, views, collections, native queries, and more.

Lifecycle

The lifecycle in creating a model in your metadata is as follows:

  1. Have some entity in your data source that you want to make queryable via your API.
  2. Introspect your data source using the DDN CLI with the relevant data connector to fetch the entity resources.
  3. Add the model to your metadata with the DDN CLI.
  4. Create a build of your supergraph API with the DDN CLI.
  5. Serve your build as your API with the Hasura engine either locally or in the cloud.
  6. Iterate on your API by repeating this process or by editing your metadata manually as needed.
Data modeling lifecycle

Create a model

To add a model you will need to have a data connector already set up and connected to the data source. Follow the relevant tutorial for your data source in How to Build with DDN to get to that point.

From a source entity

Introspect your data source:
ddn connector introspect <connector_name>

Whenever you update your data source, you can run the above command to fetch the latest resources.

Show the resources discovered from your data source:
ddn connector show-resources <connector_name>

This is an optional step and will output a list of resources that DDN discovered in your data source in the previous step.

ddn model add <connector_link_name> <collection_name>

Or you can optionally add all the models by specifying "*".

ddn model add <connector_link_name> "*"

This will add models with their accompanying metadata definitions to your metadata.

You can now build your supergraph API, serve it, and query your data.

Context for CLI commands

Note that the above CLI commands work without also adding the relevant subgraph to the command with the --subgraph flag because this has been set in the CLI context. You can learn more about creating and switching contexts in the CLI context section.

For a walkthrough on how to create a model, see the Model Tutorials section.

Via native query

You can use the query syntax of the underlying data source to create a native query and expose it as a model in your supergraph API.

The process of adding a native query is more or less unique for each data connector as each data source by nature has its own syntax.

The process for adding a native query for PostgreSQL is:

  • Create a new SQL file in your connector directory.
  • Name the file with how you want to reference it in your supergraph API.
  • Add the SQL for your native query to the file.
  • Use the DDN CLI plugin for the PostgreSQL connector to add the native query to the connector's configuration eg:
Add the native query to the connector's configuration:
ddn connector plugin \
--connector subgraph_name/connector/connector_name/connector.yaml \
-- native-operation create \
--operation-path path/to/sql_file_name.sql \
--kind query
  • Introspect your PostgreSQL data connector to fetch the latest resources.
ddn connector introspect <connector_name>
  • Show the found resources to see the new native query.
ddn connector show-resources <connector_name>
  • Add the model for the native query.
ddn model add <connector_link_name> <model_name>
  • Rebuild and serve your supergraph API.

Find out more about native queries for PostgreSQL here.

Update a model

If you want to update your model to reflect a change that happened in the underlying data source you should first introspect to get the latest resources and then update the relevant model.

Introspect your data source:
ddn connector introspect <connector_name>
Then, update your existing model:
ddn model update <connector_link_name> <model_name>

You will see an output which explains how new resources were added or updated in the model.

You can now build your supergraph API, serve it, and query your data with the updated model.

You can also update the model by editing the metadata manually.

For a walkthrough on how to update a model, see the Model Tutorials section.

Extend a model

A model can be extended in order to return nested data or to enrich or add to the data.

For example you can extend a model like Customers to also return the related Orders for each customer.

Or you can add a custom piece of logic on a model like Orders to compute and return the current currency conversion of the total price of the order.

The way this is done is via a Relationship. Read more about creating relationships here.

Delete a model

If you no longer need a model, you can delete it:
ddn model remove users

In addition to removing the Model object itself, the DDN CLI will also remove the associated metadata definitions.

Tutorials

The tutorials below follow on from each particular tutorial in the How to Build with DDN section. Select the relevant data connector to follow the tutorial.

Creating a model

To query data from your API, you'll first need to create a model that represents that data.

From a source entity

Via a new table or view

Create a new table or view in your PostgreSQL database:
CREATE TABLE public.comments (
id serial PRIMARY KEY,
comment text NOT NULL,
user_id integer NOT NULL,
post_id integer NOT NULL
);

INSERT INTO public.comments (comment, user_id, post_id)
VALUES
('Great post! Really enjoyed reading this.', 1, 2),
('Thanks for sharing your thoughts!', 2, 1),
('Interesting perspective.', 3, 1);
Use the DDN CLI to introspect your PostgreSQL instance:
ddn connector introspect my_pg
Then, add your model:
ddn model add my_pg comments
Create a new build:
ddn supergraph build local
Start your services:
ddn run docker-start
Open your development console:
ddn console --local
You can now query your table:
query {
comments {
id
comment
user_id
post_id
}
}
With a response like this:
{
"data": {
"comments": [
{
"id": 1,
"comment": "Great post! Really enjoyed reading this.",
"user_id": 1,
"post_id": 2
},
{
"id": 2,
"comment": "Thanks for sharing your thoughts!",
"user_id": 2,
"post_id": 1
},
{
"id": 3,
"comment": "Interesting perspective.",
"user_id": 3,
"post_id": 1
}
]
}
}

Via native query

Within your connector's directory, you can add a new file with a .sql extension to define a native query.

Create a new directory to store your native queries:
mkdir -p app/connector/my_pg/native_operations/queries/
Create a new file in your connector's directory:
-- native_operations/queries/order_users_of_same_age.sql
SELECT
id,
name,
age,
RANK() OVER (PARTITION BY age ORDER BY name ASC) AS rank_within_age
FROM
users
WHERE
age = {{ age }}

Arguments are passed to the native query as variables surrounded by double curly braces {{ }}.

Then, use the PostgreSQL connector's plugin to add the native query to your connector's configuration:
ddn connector plugin \
--connector app/connector/my_pg/connector.yaml \
-- \
native-operation create \
--operation-path native_operations/queries/order_users_of_same_age.sql \
--kind query
Introspect your PostgreSQL instance:
ddn connector introspect my_pg
Show the found resources:
ddn connector show-resources my_pg
Then, add your model:
ddn model add my_pg order_users_of_same_age

Let's add a few more users to make this native query example more interesting:

INSERT INTO users (name, age) VALUES ('Dan', 25), ('Erika', 25), ('Fatima', 25), ('Gabe', 25);
ddn supergraph build local
ddn run docker-start

Now in your console you can run the following query to see the results:

query UsersOfSameAge {
orderUsersOfSameAge(args: { age: 25 }) {
id
name
age
orderWithinAge
}
}

Updating a model

Your underlying data source may change over time. You can update your model to reflect these changes.

You'll need to update the mapping of your model to the data source by updating the DataConnectorLink object.

Introspect your data source:
ddn connector introspect <connector_name>
Then, update your model:
ddn model update <connector_link_name> <model_name>

This will find changed resources in the data source and attempt to merge them into the model.

If you'd like to completely add the model again, you can first run the model remove command (below) and then re-create your model.

Extending a model

Find tutorials about extending a model with related information or custom logic in the Relationships section.

Deleting a model

If you no longer need a model, you can delete it:
ddn model remove users

Reference

You can learn more about models in the metadata reference docs.