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.
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"
:[
],
"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.
To modify the schema, you must point the driver to use the .rest file we just created.
For example:
This will make the Autonomous REST connector use this configuration instead of sampling the API every time you connect.
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:
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.
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.
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.
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.