Postgres jsonbpopulaterecord() function
Casts a JSONB object to a record
The jsonb_populate_record function is used to populate a record type with values from a JSONB object. It is useful for parsing JSONB data received from external sources, particularly when merging it into an existing record.
Function signature
Section titled “Function signature”jsonb_populate_record(base_record ANYELEMENT, json JSONB) -> ANYELEMENTThis function takes two arguments: a base record of a row type (which can even be a NULL record) and a JSONB object. It returns the record updated with the JSONB values.
Example usage
Section titled “Example usage”Consider a database table that tracks employee information. When you receive employee information as JSONB records, you can use jsonb_populate_record to ingest the data into the table.
Here we create the employees table with some sample data.
CREATE TABLE employees (
id INT,
name TEXT,
department TEXT,
salary NUMERIC
);To illustrate, we start with a NULL record and cast the input JSONB payload to the employees record type.
INSERT INTO employees
SELECT *
FROM jsonb_populate_record(
NULL::employees,
'{"id": "123", "name": "John Doe", "department": "Engineering", "salary": "75000"}'
)
RETURNING *;This query returns the following result:
| id | name | department | salary |
|----|----------|-------------|--------|
| 123| John Doe | Engineering | 75000 |Advanced examples
Section titled “Advanced examples”Handling partial data with jsonb_populate_record
Section titled “Handling partial data with jsonb_populate_record”For data points where the JSONB objects have missing keys, jsonb_populate_record can still cast them into legible records.
Say we receive records for a bunch of employees who are known to be in Sales, but the department field is missing from the JSONB payload. We can use jsonb_populate_record with the default value specified for a field while the other fields are populated from the JSONB payload, as in this example:
INSERT INTO employees
SELECT *
FROM jsonb_populate_record(
(1, 'ABC', 'Sales', 0)::employees,
'{"id": "124", "name": "Jane Smith", "salary": "68000"}'
)
RETURNING *;This query returns the following:
| id | name | department | salary |
|----|------------|------------|--------|
| 124| Jane Smith | Sales | 68000 |Using jsonb_populate_record with custom types
Section titled “Using jsonb_populate_record with custom types”The base record doesn't need to have the type of a table row and can be a custom Postgres type too. For example, here we first define a custom type address and use jsonb_populate_record to cast a JSONB object to it:
CREATE TYPE address AS (
street TEXT,
city TEXT,
zip TEXT
);
SELECT *
FROM jsonb_populate_record(
NULL::address,
'{"street": "123 Main St", "city": "San Francisco", "zip": "94105"}'
);This query returns the following result:
| street | city | zip |
|------------|---------------|-------|
| 123 Main St| San Francisco | 94105 |Additional considerations
Section titled “Additional considerations”Alternative options
Section titled “Alternative options”- jsonb_to_record - It can be used similarly, with a couple differences.
jsonb_populate_recordcan be used with a base record of a pre-defined type, whereasjsonb_to_recordneeds the record type defined inline in theASclause. Further,jsonb_populate_recordcan specify default values for missing fields through the base record, whereasjsonb_to_recordmust assign them NULL values. jsonb_populate_recordset- It can be used similarly to parseJSONB, the difference being that it returns a set of records instead of a single record. For example, if you have an array ofJSONBobjects, you can usejsonb_populate_recordsetto convert each object into a new row.- json_populate_record - It has the same functionality to
jsonb_populate_record, but acceptsJSONinput instead ofJSONB.