psql return code if zero rows found - linux

I would like for my psql command to fail if zero rows are found:
psql -U postgres -d db -c "select * from user where id=1 and name='Joe';"
I want to be able to check the return value. Return 0 from the process(!) if at least one row exists and return non-zero from the psql process if no such row exists. How can I set a return code if no rows are found?

I don't think psql can do it by itself, but if you just want to see if there are any rows or not with the exit status you could combine it like
psql -U postgres -d db -t -c "select * from user where id=1 and name='Joe'" | egrep .
That will cause egrep to exit with non-zero if it cannot match anything. The -t will make it not print the column headers and summary information, so you may need to tweak this command line if you need that stuff.

Related

How to display as a table combined output of a program and a file and watch it in 1 sec

I have a program isig, that displays 18 rows of data, want to combine it with text file info1.txt that also has 18 rows of additional data into a table view and watch it in 1sec interval.
My command to display the table is:
pr -m -t <(isig 4001+18) info1.txt
And if I add watch:
watch -n 1 'pr -m -t <(isig 4001+18) info1.txt'
I get:
sh: 1: Syntax error: "(" unexpected
Is there a way to achieve this in bash command line
Process substitution (<()) is a Bash extension, not available in standard shell. Get watch to run your command in Bash instead:
watch -n 1 'bash -c "pr -m -t <(isig 4001+18) info1.txt"'

Why I get an error when I try to execute a command remotely?

I have a problem about execute command remotely via SSH. I am trying below.
ssh xx.xx.xx.xx "psql -U qradar -c "select count(id) from offense_view where to_timestamp(start_time/1000) > NOW() - interval '180 minutes'"
It gives an error like:
Pseudo-terminal will not be allocated because stdin is not a terminal.
ERROR: syntax error at or near "180"
LINE 1: ... to_timestamp(start_time/1000) > NOW() - interval 180 minute...
The problem is that you're using double quotes to delimit the argument to ssh and also the argument to psql inside the command. This is causing your strings to be parsed incorrectly. You're also missing the ending double quote for the psql command.
Nesting quotes is tricky in shell, and it's even harder when you're using ssh. It's easier if you use a here-doc.
ssh xx.xx.xx.xx <<EOF
psql -U qradar -c "select count(id) from offense_view where to_timestamp(start_time/1000) > NOW() - interval '180 minutes'"
EOF

Impala-shell Command Argument List Too Long

I have a 1,700 lines query to be executed in Impala-shell. I created a shell script with below command:
impala-shell -V -i hostname -q "[QUERY]"
However, when I executed it using sh script.sh, I got the error message "Argument list too long". I am able to run simpler/short query using Impala-shell command.
I also tried to enlarge the limit by running command ulimit -s 65536 but I got the same error.
I suspect the number of lines of the query is too big.
-f option is the answer. I prepared a separate SQL file and it worked.
impala-shell -V -i hostname -f file.sql

Cassandra : OperationTimedOut: errors={}, last_host=127.0.0.1

I am trying "select count(*) from users;" on cassandra but after waiting for 10 seconds (approx) i am getting "OperationTimedOut: errors={}, last_host=127.0.0.1". I am trying this on cqlsh. cqlsh and cassandra versions are below.
cqlsh 5.0.1 | Cassandra 3.0.8
I found few solutions on stackoverflow. But none of them is working. I tried below.
In file cassandra/conf/cassandra.yaml i increased few request_time_out settings and than restarted the cassandra
I created file cqlshrc in folder .cassandra and added below in that file
[connection]
client_timeout = 2000000
Few solution in stackoverflow are suggesting to increase some timeout field in file cqlsh, but File '/cassandra/bin/cqlsh' doesn't have any such field, so i didn't change anything in that file. cqlsh file content is below
python -c 'import sys; sys.exit(not (0x020700b0 < sys.hexversion < 0x03000000))' 2>/dev/null \
&& exec python "python -c "import os;print(os.path.dirname(os.path.realpath('$0')))"/cqlsh.py" "$#"
for pyver in 2.7; do
which python$pyver > /dev/null 2>&1 && exec python$pyver "python$pyver -c "import os;print(os.path.dirname(os.path.realpath('$0')))"/cqlsh.py" "$#"
done
echo "No appropriate python interpreter found." >&2
exit 1
Solutions please.
If the Cassandra server is working correctly, the timeout exception raises because the server can't handle the request. Is 'users' table too large?
One solution to count big tables is use the 'counter' type in another table.
For example, we can create a table like this:
CREATE TABLE custom_counters
(name varchar,
count counter,
PRIMARY KEY (name)
);
Every time we insert a user in 'users' table, we update its counter in the 'custom_counters' table:
UPDATE custom_counters
SET count = count + 1
WHERE name='users';
So, when we need to know the number of users, we have to request that field:
SELECT count FROM custom_counters WHERE name = 'users';
More info here: https://docs.datastax.com/en/cql/3.1/cql/cql_using/use_counter_t.html

Using Postgres transactions in linux shell script

I'm developing a shell script that loops through a series of Postgres database table names and dumps the table data. For example:
# dump data
psql -h $SRC_IP_ADDRESS -p 5432 -U postgres -c "BEGIN;" AWARE
do
:
pg_dump -U postgres -h $IP_ADDRESS -p 5432 -t $i -a --inserts MYDB >> \
out.sql
done
psql -h $IP_ADDRESS -p 5432 -U postgres -c "COMMIT;" MYDB
I'm worried about concurrent access to the database, however. Since there is no database lock for Postgres, I tried to wrap a BEGIN and COMMIT around the loop (using psql, as shown above). This resulted in an error message from the psql command, saying that:
WARNING: there is no transaction in progress
Is there any way to achieve this? If not, what are the alternatives?
Thanks!
Your script has two main problems. The first problem is practical: a transaction is part of a specific session, so your first psql command, which just starts a transaction and then exits, has no real effect: the transaction ends when the command completes, and later commands do not share it. The second problem is conceptual: changes made in transaction X aren't seen by transaction Y until transaction X is committed, but as soon as transaction X is committed, they're immediately seen by transaction Y, even if transaction Y is still in-progress. This means that, even if your script did successfully wrap the entire dump in a single transaction, this wouldn't make any difference, because your dump could still see inconsistent results from one query to the next. (That is: it's meaningless to wrap a series of SELECTs in a transaction. A transaction is only meaningful if it contains one or more DML statements, UPDATEs or INSERTs or DELETEs.)
However, since you don't really need your shell-script to loop over your list of tables; rather, you can just give pg_dump all the table-names at once, by passing multiple -t flags:
pg_dump -U postgres -h $IP_ADDRESS -p 5432 \
-t table1 -t table2 -t table3 -a --inserts MYDB >> out.sql
and according to the documentation, pg_dump "makes consistent backups even if the database is being used concurrently", so you wouldn't need to worry about setting up a transaction even if that did help.
(By the way, the -t flag also supports a glob notation; for example, -t table* would match all tables whose names begin with table.)

Resources