Can anyone see why this does not work? According to section 9.15 of the manual, the ->
operator should access elements of a JSON data type. It looks to me like although the info schema says the column is type 'json' it is still really a scalar string (note the quotes when it is displayed.)
postgres=# create table jtest (id serial, data json);
CREATE TABLE
postgres=# select column_name, data_type from information_schema.columns where table_name = 'jtest';
column_name | data_type
-------------+-----------
id | integer
data | json
(2 rows)
postgres=# insert into jtest (data) values (to_json('{"k1": 1, "k2": "two"}'::text));
INSERT 0 1
postgres=# select * from jtest;
id | data
----+--------------------------------
1 | "{\"k1\": 1, \"k2\": \"two\"}"
(1 row)
postgres=# select data->'k1' from jtest;
ERROR: cannot extract element from a scalar
postgres=# select data::json->'k1' from jtest;
ERROR: cannot extract element from a scalar
postgres=# \q
$ pg_ctl --version
pg_ctl (PostgreSQL) 9.3beta2
Update:
I found these two posts here and here that indicate it should work exactly as I am doing. Just to be sure I tried this:
postgres=# select * from jtest where data ->> 'k2' = 'two';
ERROR: cannot extract element from a scalar
Is there a build option or contrib module I need to get JSON functionality?
Querying the JSON documentPostgreSQL has two native operators -> and ->> to query JSON documents. The first operator -> returns a JSON object, while the operator ->> returns text. These operators work on both JSON as well as JSONB columns. There are additional operators available for JSONB columns.
PostgreSQL offers two types for storing JSON data: json and jsonb . To implement efficient query mechanisms for these data types, PostgreSQL also provides the jsonpath data type described in Section 8.14. 7. The json and jsonb data types accept almost identical sets of values as input.
To query JSON data, you can use standard T-SQL. If you must create a query or report on JSON data, you can easily convert JSON data to rows and columns by calling the OPENJSON rowset function. For more information, see Convert JSON Data to Rows and Columns with OPENJSON (SQL Server).
You can save any valid json value to either json or to a jsonb column. But you cannot bind it as string/ text / varchar , if you use prepared statements (use casts instead in sql, like UPDATE ... SET json_col = $1::json or bind it as unknown ).
It appears that my mistake was using the to_json() function when inserting the data. That resulted in a JSON-encoded string containing my data. I did not find anything in the postgresql docs showing how to insert JSON data, but I did eventually find this post here that showed an example. I should have done:
postgres=# insert into jtest (data) values ('{"k1": 1, "k2": "two"}');
INSERT 0 1
postgres=# select * from jtest;
id | data
----+------------------------
1 | {"k1": 1, "k2": "two"}
(1 row)
(note the lack of quotes on the value in the data column.)
Now it works:
postgres=# select * from jtest where data ->> 'k2' = 'two';
id | data
----+------------------------
1 | {"k1": 1, "k2": "two"}
(1 row)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With