Infer ABL schemas from JSON data
- Last Updated: January 12, 2026
- 4 minute read
- OpenEdge
- Version 13.0
- Documentation
The READ-JSON( ) method has to infer a
schema when its target ABL data object does not have a schema. Unlike XML, JSON does not have
a standard schema language. Because the format of each JSON value indicates its data type, the
AVM can infer a schema from the source, whether it is a JSON string, a Progress.Json.ObjectModel.JsonArray, or a Progress.Json.ObjectModel.JsonObject.
When the AVM has to infer schema for the data object, the AVM makes two passes through the JSON data: one to build the schema and one to fill in the data. On the first pass, the AVM reads all the records before finalizing the schema, which has the following effects:
- When the AVM parses a JSON
null, it provisionally assigns aCHARACTERdata type to the column. If a subsequent record includes a non-null value for that column, the AVM assigns that data type to the column. In either case, the AVM equates the JSONnullvalue to the Unknown value (?). - If different rows contain different fields, the final schema includes all the fields.
The AVM infers ABL schema from JSON data using the following guidelines:
- Any JSON object containing an array of objects is a temp-table. The temp-table's name is the array's name.
- The entries in an array of objects are the rows of a single temp-table.
- Each name/value pair in a row's object is a column in the temp-table. The column's name is the JSON value's name.
- If a value in a row object is a JSON array, it is an array column. The AVM infers the data type of the array column from the first value in the inner array.
- Any JSON object that is not an array of objects, but that contains at least one object from which the AVM infers a temp-table, is a ProDataSet. The ProDataSet's name is the JSON object's name.
- If the AVM encounters an array of objects within another array of objects, the AVM infers it to be a nested temp-table inside the ProDataSet.
- If the AVM infers a temp-table nested within another inferred temp-table,
the AVM attempts to create a relationship between the two tables. If there is only one pair
of fields with matching names in the parent and child tables, the AVM creates a
data-relation between the parent table and nested child table using the matching fields for
the pairs-list. If there are no matching fields, the AVM creates a parent-id-relation
between the parent and nested child and adds a
RECIDfield to the child table to maintain the relationship. If there is more than one pair of matching fields between the tables, the AVM generates an error message and theREAD-JSON( )method returnsFALSE.
READ-JSON( ) on a
temp-table object and the AVM infers a nested temp-table, the method generates an error
message and returns FALSE. If you call READ-JSON( ) on a ProDataSet object and the JSON data contains only
a temp-table, the method generates an error message and returns FALSE. The following table shows how the AVM maps JSON data types to ABL data types when inferring the schema of a temp-table. By comparing the following table with Table 7, you can see that the differences in the data type mapping make it unlikely that an inferred temp-table matches the original object from which the data was read.
| JSON value | ABL data type |
|---|---|
string1 |
CHARACTER
|
number2 |
DECIMAL
|
boolean (true or
false) |
LOGICAL
|
null |
CHARACTER
|
CHARACTER data type in ABL. For example, a JSON string value in ISO 8601
format is interpreted as a CHARACTER field, not a DATETIME
field.As an example for the inferring process, take the following JSON object:
|
The JSON object contains an array name, "ttCust". The AVM
sees that it is an array of objects and creates a temp-table named ttCust to
hold the data. The first name/value pair in the row's object is an array of JSON
string values named "Name". The AVM creates a CHARACTER field, Name, of EXTENT 3 as the temp-table's first column. The next name/value pair
is a JSON number named "CustNum". The AVM creates a DECIMAL field, CustNum, as the second column. The
final name/value pair contains a JSON null named
"GoldStatus". Because the value is a null, the AVM
temporarily chooses CHARACTER as the final column's data
type. The AVM then reads the next record and determines that it contains a JSON
boolean for the final pair and creates a LOGICAL field, GoldStatus, as the final
column.
The following procedure reads the output from write-json-pds2.p into a dynamic ProDataSet, inferring the ProDataSet's schema from the JSON data. It then outputs the schema and data to another file, so you can examine the results:
|
The output from write-json-pds2.p is designed
with the READ-JSON( ) method's inferring
feature in mind. The ProDataSet's tables have only one possible
foreign key between each pair of nested tables. If you ran write-json-pds2.p substituting
the following ProDataSet definition for the include file and then
ran read-json-infer-pds2.p on the output, the
procedure would generate several errors because there are several
fields in each table that match fields in the outer tables.
|