0

I wan't to schedule a SQL query in a PostgreSQL database with a crontab.

In terminal, in root, when I run:

psql -U postgres -d my_database -h localhost -p 5432 -c "INSERT INTO schema.table (name) VALUES ('Insert with a command from terminal');"

It asking me a password. So I add it:

PGPASSWORD="mypassword" psql -U postgres -d my_database -h localhost -p 5432 -c "INSERT INTO schema.table (name) VALUES ('Insert with a command from terminal and password');"

And when I run the same in the crontab, It doesn't succed:

0 12 * * * PGPASSWORD="mypassword" psql -U postgres -d my_database -h localhost -p 5432 -c "INSERT INTO schema.table (name) VALUES ('Insert with a command from crontab and password');"

The crontab log return me

nano var/log/syslog

(root) CMD (PGPASSWORD="mypassword" psql -U postgres -d my_database -h localhost -p 5432 -c "INSERT INTO schema.table (name) VALUES ('Insert with a command from crontab and password');")
CRON[15504]: (CRON) info (No MTA installed, discarding output)
CRON[15677]: (root) CMD (command -v debian-sa1 > /dev/null && debian-sa1 1 1)
crontab[15862]: (root) BEGIN EDIT (root)
systemd[1]: session-60285.scope: Succeeded.
crontab[15862]: (root) END EDIT (root)

Why the crontab job doesn't execute the pgsql command ? How can I schedule a SQL command with crontab ?

1 Answer 1

3

Some implementations of cron (I think including the one that comes with Debian) lets you set the environment variables on previous lines:

PGPASSWORD="mypassword" 
0 12 * * * psql -U postgres -d my_database -h localhost -p 5432 -c "INSERT INTO schema.table (name) VALUES ('Insert with a command from crontab and password');"

Does this have to be a cron job? Since you're running Debian, you could make use of systemd's timers.

To implement this in systemd you would write a timer unit that schedules the job and a service unit that runs the job. The service unit can have environment variables set.

#/etc/systemd/system/regularquery.timer
[Unit]
Description="Timer to run SQL query"
After=postgresql.service

[Timer]
OnCalendar=*-*-* 12:00:00
Unit=regularquery.service

[Install]
WantedBy=multi-user.target
#/etc/systemd/system/regularquery.service
[Unit]
Description="SQL Query

[Service]
Type=oneshot
User=postgres
Environment=PGPASSWORD="mypassword"
ExecStart=/usr/bin/psql -U postgres -d my_database -h localhost -p 5432 -c "INSERT INTO schema.table (name) VALUES ('Insert with a command from terminal');"

Try it out with sudo systemctl start regularquery.service and see if it connects fine. You can monitor the output with journalctl -u regularquery.service. When you're happy, get the thing scheduled with sudo systemctl enable --now regularquery.timer


Alternatively, I found this in man psql:

       -w
       --no-password
           Never issue a password prompt. If the server requires password
           authentication and a password is not available from other sources
           such as a .pgpass file, the connection attempt will fail. This
           option can be useful in batch jobs and scripts where no user is
           present to enter a password.

This suggests that ~/.pgpass might be a good alternative to an environment variable. It also suggests --no-password is a good switch for a non-user session (i.e. crontab or systemd) as it will NEVER interactively pause for a prompt.

1
  • As you suggest, I place environment variables on previous lines, everything ok this time. Thanks also for your alternative with systemd's timers, I didn't know this method.
    – GeoGyro
    Feb 15, 2022 at 15:40

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .