0

I am making a query as user postgres via my current user, xyz. I am returning the results of this query as JSON. I want to save this (huge) JSON into a file owned by my current user xyz. And I do not want to login again as user postgres to chmod it etc.

Below code demonstrates what I can do so far by using COPY() TO PROGRAM 'cat>/tmp/out1 && chmod 777 /tmp/out1' . The problem is that after copying /tmp/out1 to my homedir there still is /tmp/out1 with postgres ownership which I need to login/sudo as postgres again in order to delete it. I want to avoid this second login.

chown'ing the file (as the owner user postgres) to my user is not permitted because of my particular system permissions (which are default AFAICS).

Dumping output from psql either via a cli redirect includes not only the JSON but also lots of other "rubbish".

Are there any other ways to tell psql to dump the JSON only so that I can redirect stdout to my own file?

My search has yielded this: Change permissions of postgres copy to exported file which unfortunately does not work, chgrp et.al. says Operation not permitted.

Code to play with, it is part of a much larger setting which interrogates a postgis OpenStreetMap database. My OS is linux and Pg is latest version.

psql -U postgres -d mygisdb -a <<EOS
--- something to test with, this is part of a much bigger setting
create table if not exists mytable (name VARCHAR(255));
insert into mytable (name) VALUES ('hello');
COPY(
    SELECT jsonb_build_object(
      'type', 'FeatureCollection',
      'features', jsonb_agg(feature)
    ) AS geojson_output
    FROM (
      SELECT jsonb_build_object(
        'type', 'Feature',
        'properties', jsonb_build_object(
            'name', name
        )
      ) AS feature
      FROM mytable
   ) AS subquery) TO PROGRAM 'cat > /tmp/out1 && chmod 755 /tmp/out1';
EOS
cp /tmp/out1 ~/myfilenow
# now I want to delete /tmp/out1
# this does not work
# mv /tmp/out1 ~/myfilenow
  
New contributor
bliako is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1 Answer 1

2

COPY is executed by the instance owner (i.e. postgres, most of the time), so the file it creates is obviously owned by that user, and you cannot change that.

However, you can run psql -t -c 'SELECT ...' -o somefile, which 1) should get rid of "rubbish" and 2) will create the file owned by whoever runs the command, perhaps xyz.

P.S. Regarding "making a query as user postgres", it's not a very good idea to perform daily tasks that do not require superuser privileges as the superuser, because mistakes can be catastrophic.

4
  • thank you @mustacio, that works perfectly, I have removed the -a and added the -t and removed the COPY(). I hope that with above cli params there will NEVER be any extraneous info/data on the output except the JSON. I do not understand your 2nd point. I am logged in as ordinary user (xyz) and run psql using psql -U postgres ... I thought this was the way to go, create a postgres user which is not superuser and do all the queries through that account. (edited to remove something wrong in the last line). Commented Nov 15 at 18:47
  • 1
    The -U postgres is the superuser. Commented Nov 16 at 8:13
  • I get it. thanks. I will create a user specifically for this db. Give ownership of the db to this user and then use psql -U myuser. Commented Nov 17 at 20:13
  • The user does not need ownership of the database, just the privilege to connect and select from the necessary tables. Commented Nov 17 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.