ODBC TUTORIAL

Query any REST API using ODBC in 5 mins – Editing the auto generated schema (Part 3)

Updated: 19 Aug 2024

Introduction

Editor's Note: Progress DataDirect Autonomous REST Connector's User Interface (UI) simplifies the connectivity process. Read the Getting Started tutorial to learn more.

In Part 1 and Part 2 of the tutorial series, we learned how you can sample and connect to multiple endpoints and query the data using SQL, without having to write a line of code. If you are new, recommend you start from Part 1.

When sampling REST endpoint, the Autonomous REST Connector heuristically generates a relational schema, including column names and data types, that should be user friendly. There can be situations where you might want to rename a table or field name to a value that avoids confusion, change the data type to one that you think is appropriate, or change the primary key to a different field. In this tutorial, we will guide you through the process of editing your schema to make these changes.

Get the auto-generated REST configuration

In part 2 of this tutorial series, we created a model file to specify the table names and the endpoints to sample.


This is the REST model in its simplest form. When you connect using a model file, Autonomous REST connector samples all the endpoints, normalizes the JSON structure to a relational schema and infers the metadata. All the mappings which it infers are stored in memory and you can access it by querying the _CONFIGURATION table.

In your database/query tool, such as WinSQL, Run the below query to get the auto-generated REST configuration created by Autonomous REST Connector.

SELECT * FROM _CONFIGURATION

Copy the data from CONTENT column to a text editor and paste it. It should take the following form:

{
    "categories":{
        "#path":[
            "https://api.yelp.com/v3/categories /categories"
        ],
        "alias":"VarChar(48)",
        "title":"VarChar(52),#key",
        "parent_aliases[]":"VarChar(34)",
        "country_whitelist[]":"VarChar(3)",
        "country_blacklist[]":"VarChar(3)"
    },
    "events":{
        "#path":[
            "https://api.yelp.com/v3/events"
        ],
        "events[]":{
            "attending_count":"Integer",
            "category":"VarChar(64)",
            "cost":"VarChar(64)",
            "cost_max":"VarChar(64)",
            "description":"VarChar(238)",
            "event_site_url":"VarChar(310)",
            "id":"VarChar(75)",
            "image_url":"VarChar(102)",
            "interested_count":"Integer",
            "is_canceled":"Boolean",
            "is_free":"Boolean",
            "is_official":"Boolean",
            "latitude":"Double",
            "longitude":"Double",
            "name":"VarChar(64)",
            "tickets_url":"VarChar(64)",
            "time_end":"Timestamp(0)",
            "time_start":"Timestamp(0)",
            "location":{
                "address1":"VarChar(64)",
                "address2":"VarChar(64)",
                "address3":"VarChar(64)",
                "city":"VarChar(64)",
                "zip_code":"Integer",
                "country":"VarChar(64)",
                "state":"VarChar(64)",
                "display_address[]":"VarChar(64)",
                "cross_streets":"VarChar(64)"
            },
            "business_id":"VarChar(64)"
        },
        "total":"Integer,#key"
    },
    "business":{
        "#path":[
        ],
        "businesses[]":{
            "id":"VarChar(64)",
            "alias":"VarChar(64)",
            "name":"VarChar(64)",
            "image_url":"VarChar(102)",
            "is_closed":"Boolean",
            "url":"VarChar(295)",
            "review_count":"Integer",
            "categories[]":{
                "alias":"VarChar(21)",
                "title":"VarChar(33)"
            },
            "rating":"Double",
            "coordinates":{
                "latitude":"Double",
                "longitude":"Double"
            },
            "transactions[]":"VarChar(64)",
            "price":"VarChar(64)",
            "location":{
                "address1":"VarChar(64)",
                "address2":"VarChar(64)",
                "address3":"VarChar(64)",
                "city":"VarChar(64)",
                "zip_code":"Integer",
                "country":"VarChar(64)",
                "state":"VarChar(64)",
                "display_address[]":"VarChar(40)"
            },
            "phone":"VarChar(64)",
            "display_phone":"VarChar(64)",
            "distance":"Double"
        },
        "total":"Integer,#key",
        "region":{
            "center":{
                "longitude":"Double",
                "latitude":"Double"
            }
        },
        "location":{
            "#type":"VarChar(64),#key",
            "#virtual":true,
            "#default":"27617",
            "#eq":"location"
        }
    }
}

Save your text file with a .rest extension. In the following examples, we will use the name YelpAuto.rest.

Using the updated REST Model file

To modify the schema, you must point the driver to use the .rest file we just created.

  1. Using the ODBC Administrator, open your data source definition you created in Part 1 in the Configuration Manger.
  2. In the REST Config File field, specify the path to the Model file you just created.

For example:

7

This will make the Autonomous REST connector use this configuration instead of sampling the API every time you connect.

Understanding the REST Config file

If you compare the model file we just created (YelpAuto.rest) against the simple one we created in Part 2 (yelp.rest), you will notice that the Autonomous REST Connector has populated the entries for the original endpoints with properties and nested objects from the service response, as well as assigned a data type for the fields. For example, here is the resolved entry for the categories endpoint:

#path: Specifies the endpoint that is sampled for the parent and child tables.

#key: Indicates the field that has been assigned as the primary key. In this example, the field named alias has been designated the primary key.

In the next example, we will look at an entry for an endpoint that required a query parameter. If you recall, the for the business search endpoint, we set a query parameter for the location field:

https://api.yelp.com/v3/businesses/search?location=27617


Now let us look at the resolved model entry for the location table:

"location":{
            "#type":"VarChar(64),#key",
            "#virtual":true,
            "#default":"27617",
            "#eq":"location"
}

Notice the following elements that we did not see in our earlier example:

  • #virtual: Setting this parameter to true exposes the field as a virtual column. This is used when the field does not appear in the response as a simple key value pair.
  • #default: Specifies the default value used to filter the result if none is provided by the SQL query. For example, we set a value of 27617 in Part 2 of the tutorial.
  • #eg: Specifies the query parameter name that must be sent to the service.

Change the Primary Key

You can easily change the primary key to a different field by using #keyelement. For example, in the categories table, let's change the primary key from the alias field to the title field. To designate the title field as the primary key, remove the #key element from the alias field entry and add it to the title entry. The updated syntax should take the following form:

"categories":{
        "#path":[
            "https://api.yelp.com/v3/categories /categories"
        ],
        "alias":"VarChar(48),
        "title":"VarChar(52),#key",
        "parent_aliases[]":"VarChar(34)",
        "country_whitelist[]":"VarChar(3)",
        "country_blacklist[]":"VarChar(3)"
    }

The next time you connect, the driver will read the changes in the Model file and your new primary key for the categorizes table will be the title field.

Change column names

You can change the name of the column in the relational schema by adding the new column name in angled brackets after the original name:

old_column_name<new_column_name>:ata_type(xx)


For example, the following syntax would rename the column alias to categorycode in the categories table

"categories":{
        "#path":[
            "https://api.yelp.com/v3/categories /categories"
        ],
        "alias<categorycode>":"VarChar(48),#key",
        "title":"VarChar(52)",
        "parent_aliases[]":"VarChar(34)",
        "country_whitelist[]":"VarChar(3)",
    }

When you reconnect, the driver will read the updated Model file and apply your changes.

Change Data types

You can also change the default data type mapping for a column to any of those supported by the driver. A list of supported data types is available here.

"categories":{
        "#path":[
            "https://api.yelp.com/v3/categories /categories"
        ],
        "alias<categorycode>":"LONGVARCHAR(32000),#key",
        "title":"VarChar(52) ",
        "parent_aliases[]":"VarChar(34)",
        "country_whitelist[]":"VarChar(3)",
        "country_blacklist[]":"VarChar(3)"
    }

When you reconnect, the driver will read the updated Model file and apply your changes.

Change table names

When generating the relational schema from your endpoints, the Autonomous REST Connector sometimes generates ambiguous or non-desirable table names. If that occurs, you might want to manually change the name of your table.

For example, you might encounter a endpoint with a nested object that contains the same name. This may result in similarly named tables. You can see this in the relational mapping of the business endpoint, where there are tables named CATEGORIES and CATEGORIES_1.

CATEGORIES is the table that was created by sampling Categories endpoint. It contains all the categories that Yelp offers.

CATEGORIES_1 is one of the table that was created by sampling Businesses endpoint. If you look at the response from businesses endpoint, it contains a nested JSON array of categories to which that business is applicable.

To avoid confusion, rename the CATEGORIES_1 table BUSINESS_CATEGORY. You can rename tables using the following syntax:

"old_table_name<new_table_name>[]":{}


Example:

"business":{
        "#path":[
        ],
        "businesses[]":{
            "id":"VarChar(64)",
            "alias":"VarChar(64)",
            "name":"VarChar(64)",
            "image_url":"VarChar(102)",
            "is_closed":"Boolean",
            "url":"VarChar(295)",
            "review_count":"Integer",
            "categories<business_category>[]":{
                "alias":"VarChar(21)",
                "title":"VarChar(33)"
            },
            "rating":"Double",
            "coordinates":{
                "latitude":"Double",
                "longitude":"Double"
            },
            "transactions[]":"VarChar(64)",
            "price":"VarChar(64)",
            "location":{
                "address1":"VarChar(64)",
                "address2":"VarChar(64)",
                "address3":"VarChar(64)",
                "city":"VarChar(64)",
                "zip_code":"Integer",
                "country":"VarChar(64)",
                "state":"VarChar(64)",
                "display_address[]":"VarChar(40)"
            },
            "phone":"VarChar(64)",
            "display_phone":"VarChar(64)",
            "distance":"Double"
        },
        "total":"Integer,#key",
        "region":{
            "center":{
                "longitude":"Double",
                "latitude":"Double"
            }
        },
        "location":{
            "#type":"VarChar(64),#key",
            "#virtual":true,
            "#default":"27617",
            "#eq":"location"
        }
    }

When you reconnect, the driver will read the updated Model file and apply your changes.

You now know how to complete some basic customizations to your schema. Feel free to contact us if you have any issues.

In the next tutorial, we will look at configuring Autonomous REST Connector to page your results beyond the first page.

Connect any application to any data source anywhere

Explore all DataDirect Connectors

Need additional help with your product?

Get Customer Support