Check if json contains a value in postgres - postgresql

From my database I have formed a json data as below. I am trying to search for a value in the json data filedata
filedata = {"{\"fc_primary_key\": \"A1234567892017/06/27\"}","{\"fc_primary_key\": \"A1234567892017/06/27\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892017/08/07\"}","{\"fc_primary_key\": \"A1234567892024/03/01\"}","{\"fc_primary_key\": \"A12345678945353\"}","{\"fc_primary_key\": \"A1234567892023/11/22\"}","{\"fc_primary_key\": \"A12345678945252\"}","{\"fc_primary_key\": \"A1234567892017-07-01\"}"}
In the above data I am trying to find if there is A1234567892023/11/22 in it.
I have tried the below query
IF filedata::text #> JSONB '[{"fc_primary_key": "A1234567892023/11/22"}]'
THEN
RAISE NOTICE 'PRIMARY KEY %', 'exists';
END IF;
I am getting the error as below.
ERROR: operator does not exist: text = jsonb
LINE 1: SELECT filedata::text = JSONB '[{"fc_primary_key": "A1234567...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
Please help.

Related

Sqlalchemy filter on JSONB column by contains

I'm trying to use a JSONB column and apply a .containson it. This column value is a string list.
There is my model:
class MessageDocument(Document):
__tablename__ = "message"
id = Column(Integer, primary_key=True, autoincrement=True)
# ...
concerned = Column(JSONB(), default="[]") # list of str
And my query:
.filter(MessageDocument.concerned.contains([character.id]))
But there is the error:
E sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedFunction) operator does not exist: json #> unknown
E LINE 3: WHERE message.concerned #> '["xena"]' AND message.first_mess...
E ^
E HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
I followed up many responses here but whithout success (.astext, .as_text(), cast(...). How can I deal with my JSONB string list to do this .contains?

Text and jsonb concatenation in a single postgresql query

How can I concatenate a string inside of a concatenated jsonb object in postgresql? In other words, I am using the JSONb concatenate operator as well as the text concatenate operator in the same query and running into trouble.
Or... if there is a totally different query I should be executing, I'd appreciate hearing suggestions. The goal is to update a row containing a jsonb column. We don't want to overwrite existing key value pairs in the jsonb column that are not provided in the query and we also want to update multiple rows at once.
My query:
update contacts as c set data = data || '{"geomatch": "MATCH","latitude":'||v.latitude||'}'
from (values (16247746,40.814140),
(16247747,20.900840),
(16247748,20.890570)) as v(contact_id,latitude) where c.contact_id = v.contact_id
The Error:
ERROR: invalid input syntax for type json
LINE 85: update contacts as c set data = data || '{"geomatch": "MATCH...
^
DETAIL: The input string ended unexpectedly.
CONTEXT: JSON data, line 1: {"geomatch": "MATCH","latitude":
SQL state: 22P02
Character: 4573
You might be looking for
SET data = data || ('{"geomatch": "MATCH","latitude":'||v.latitude||'}')::jsonb
-- ^^ jsonb ^^ text ^^ text
but that's not how one should build JSON objects - that v.latitude might not be a valid JSON literal, or even contain some injection like "", "otherKey": "oops". (Admittedly, in your example you control the values, and they're numbers so it might be fine, but it's still a bad practice). Instead, use jsonb_build_object:
SET data = data || jsonb_build_object('geomatch', 'MATCH', 'latitude', v.latitude)
There are two problems. The first is operator precedence preventing your concatenation of a jsonb object to what is read a text object. The second is that the concatenation of text pieces requires a cast to jsonb.
This should work:
update contacts as c
set data = data || ('{"geomatch": "MATCH","latitude":'||v.latitude||'}')::jsonb
from (values (16247746,40.814140),
(16247747,20.900840),
(16247748,20.890570)) as v(contact_id,latitude)
where c.contact_id = v.contact_id
;

How to insert JSONB data from dependent table

I'm trying to insert data into a JSONB field based on a dependent table.
Essentially I want to do this (ignore why this is just an example query):
insert into myschema.teams (team_name, params)
select users.team_name, '{"team_name": teams.team_id, "user_name": users.username }'
from myschema.users
where users.team_name is not null;
As written I'm getting these errors:
ERROR: invalid input syntax for type json
LINE 2: ... '{"team_name...
^
DETAIL: Token "teams" is invalid.
CONTEXT: JSON data, line 1: {"team_name": teams...
You are using a string literal that doesn't contain valid JSON. There is no interpolation going on - you need use the jsonb_build_object function to create the JSONB value from dynamic values. (You could also do string concatenation and the cast from text to json, but please don't).
insert into myschema.teams (team_name, params)
select users.team_name, jsonb_build_object('team_name', teams.team_name, 'user_name', users.username)
from myschema.users
where users.team_name is not null;

How to insert value into uuid column in Postgres?

I have a table with a uuid column, and some of the rows are missing the data. I need to insert data into this uuid column. The data is entered manually, so we are suffixing with other column data to differentiate, but it gives me an error.
UPDATE schema.table
SET uuid_column = CONCAT ('f7949f56-8840-5afa-8c6d-3b0f6e7f93e9', '-', id_column)
WHERE id_column = '1234';
Error: [42804] ERROR: column "uuid_column" is of type uuid but expression is of type text
Hint: You will need to rewrite or cast the expression.
Position: 45
I also tried
UPDATE schema.table
SET uuid_column = CONCAT ('f7949f56-8840-5afa-8c6d-3b0f6e7f93e9', '-', id_column)::uuid
WHERE id_column = '1234';
Error: [22P02] ERROR: invalid input syntax for uuid: "f7949f56-8840-5afa-8c6d-3b0f6e7f93e9-1234"
An UUID consists of 16 bytes, which you see displayed in hexadecimal notation.
You cannot have a UUID with fewer or more bytes.
I recommend using the type bytea if you really need to do such a thing.

How to use comparison where operator for JSON

I get this error when querying with a json column:
(psycopg2.ProgrammingError) operator does not exist: json = text
The column is defined as JSON with SQLAlchemy:
json_data = db.Column(db.JSON, nullable=False)
How do you compare with Postgres?
There is no equality (or inequality) operator for the data type json. If you need to test the value as a whole, you might cast to jsonb:
... WHERE json_data::jsonb = jsonb '{}';
Or cast to text for simple cases:
... WHERE json_data::text = '{}';
But there are many valid text representations for the same json value - which is the reason why Postgres does not implement equality / inequality operators for the type.
See:
How to query a json column for empty objects?