How to Connect to a PostgreSQL Database from a Batch Script
PostgreSQL provides native command-line tools built for automation, psql for executing SQL and pg_dump for creating backups. Administering PostgreSQL from Windows Batch scripts reduces dependencies and enables repeatable maintenance tasks (health checks, migrations, reporting extracts, etc.).
In this guide, we will demonstrate how to connect to a local or remote PostgreSQL database using a Batch script.
The Strategy: The psql.exe Client
- Identify the PostgreSQL
bindirectory (e.g.,C:\Program Files\PostgreSQL\16\bin). - Define the connection details (Host, Port, Database, User).
- Provide authentication securely (prefer
PGPASSFILE/pgpass.conf; or usePGPASSWORDas a scoped environment variable). - Execute SQL via
-c, or run a.sqlfile via-f.
Method 1: Run an Inline SQL Statement with PGPASSWORD (Scoped)
PostgreSQL discourages putting passwords directly on the command line. A common Batch pattern is setting PGPASSWORD only for the lifetime of the script (via setlocal) and then calling psql.
@echo off
setlocal
:: Define the PostgreSQL executable
set "psqlExe=C:\Program Files\PostgreSQL\16\bin\psql.exe"
:: Define connection details
set "pgHost=127.0.0.1"
set "pgPort=5432"
set "pgUser=postgres"
set "pgDatabase=inventory_db"
:: Validate psql.exe exists
if not exist "%psqlExe%" (
echo [ERROR] psql.exe not found at "%psqlExe%".
pause
exit /b 1
)
:: Prompt for password (interactive usage)
set /p "PGPASSWORD=Enter PostgreSQL password: "
if "%PGPASSWORD%"=="" (
echo [ERROR] Password cannot be empty.
pause
exit /b 1
)
echo.
echo Connecting to PostgreSQL at %pgHost%:%pgPort% ...
echo Executing sample query...
echo.
set "query=SELECT COUNT(*) AS current_items FROM products;"
:: -X = do not read startup files (.psqlrc) for consistent automation behavior
:: -v ON_ERROR_STOP=1 = exit non-zero if the SQL fails (otherwise many SQL errors still return 0)
:: -q = quiet
"%psqlExe%" -X -q -v ON_ERROR_STOP=1 -h "%pgHost%" -p "%pgPort%" -U "%pgUser%" -d "%pgDatabase%" -c "%query%"
if %errorlevel% equ 0 (
echo.
echo ==========================================
echo EXECUTION SUCCESSFUL
echo ==========================================
) else (
echo.
echo [ERROR] psql returned error code: %errorlevel%.
pause
exit /b %errorlevel%
)
pause
endlocal
PGPASSWORD is safer than placing a password directly in the command line, but it is not fully secret: other processes running as the same user may be able to read environment variables. For unattended automation, prefer a restricted pgpass.conf (see tip below).
For non-interactive automation, use a password file instead of prompting:
- Default location:
%APPDATA%\postgresql\pgpass.conf - Or set a custom file:
set "PGPASSFILE=C:\Secure\pgpass.conf"
File format (one line per connection):
hostname:port:database:username:password
Lock down the file with NTFS permissions (only the service account should read it).
Method 2: Output Query Results to a CSV Report
For reports meant for Excel/BI tools, psql can emit real CSV. On modern PostgreSQL versions, psql supports --csv.
@echo off
setlocal
set "psqlExe=C:\Program Files\PostgreSQL\16\bin\psql.exe"
set "pgHost=10.0.1.201"
set "pgPort=5432"
set "pgUser=report_reader"
set "pgDatabase=finance_db"
set "outputCsv=C:\Reports\PaidInvoices.csv"
set "query=SELECT id, invoice_number, total FROM invoices WHERE status='PAID' ORDER BY id;"
:: Validate psql.exe exists
if not exist "%psqlExe%" (
echo [ERROR] psql.exe not found at "%psqlExe%".
pause
exit /b 1
)
:: Ensure output directory exists
for %%A in ("%outputCsv%") do (
if not exist "%%~dpA" mkdir "%%~dpA"
)
:: Prompt for password (interactive usage)
set /p "PGPASSWORD=Enter PostgreSQL password: "
if "%PGPASSWORD%"=="" (
echo [ERROR] Password cannot be empty.
pause
exit /b 1
)
echo.
echo Extracting PostgreSQL data into "%outputCsv%"...
echo.
:: --csv = CSV output
:: -o = write output directly to file (more reliable than cmd > redirection for some cases)
:: -P footer=off -P pager=off = remove "(N rows)" footer and disable paging for automation
:: -v ON_ERROR_STOP=1 = fail the script if the query fails
"%psqlExe%" -X -q -v ON_ERROR_STOP=1 ^
-h "%pgHost%" -p "%pgPort%" -U "%pgUser%" -d "%pgDatabase%" ^
--csv -P "footer=off" -P "pager=off" ^
-c "%query%" -o "%outputCsv%"
if %errorlevel% equ 0 (
echo.
echo ==========================================
echo EXTRACTION SUCCESSFUL
echo Output: %outputCsv%
echo ==========================================
) else (
echo.
echo [ERROR] psql returned error code: %errorlevel%.
pause
exit /b %errorlevel%
)
pause
endlocal
If you need server-side CSV generation (written by PostgreSQL on the server’s filesystem), use COPY ... TO 'path'. If you need client-side output (written on the machine running the script), use \copy ... TO 'path' (a psql meta-command).
Method 3: Execute a Multi-Line .sql File (Migrations / Batch SQL)
For migrations, schema changes, or long scripts, execute a .sql file with -f.
@echo off
setlocal
set "psqlExe=C:\Program Files\PostgreSQL\16\bin\psql.exe"
set "pgHost=localhost"
set "pgPort=5432"
set "pgUser=postgres"
set "pgDatabase=inventory_db"
set "sqlFile=C:\Migrations\V2_Schema_Update.sql"
:: Validate psql.exe exists
if not exist "%psqlExe%" (
echo [ERROR] psql.exe not found at "%psqlExe%".
pause
exit /b 1
)
:: Validate .sql file exists
if not exist "%sqlFile%" (
echo [ERROR] SQL file not found at "%sqlFile%".
pause
exit /b 1
)
:: Prompt for password (interactive usage)
set /p "PGPASSWORD=Enter PostgreSQL password: "
if "%PGPASSWORD%"=="" (
echo [ERROR] Password cannot be empty.
pause
exit /b 1
)
echo.
echo Executing PostgreSQL script: "%sqlFile%"...
echo.
:: -v ON_ERROR_STOP=1 makes psql stop and return non-zero if any statement fails
"%psqlExe%" -X -q -v ON_ERROR_STOP=1 -h "%pgHost%" -p "%pgPort%" -U "%pgUser%" -d "%pgDatabase%" -f "%sqlFile%"
if %errorlevel% equ 0 (
echo.
echo ==========================================
echo SCRIPT EXECUTION SUCCESSFUL
echo ==========================================
) else (
echo.
echo [ERROR] psql returned error code: %errorlevel%.
pause
exit /b %errorlevel%
)
pause
endlocal
Why Connect to PostgreSQL from Batch?
- Backup Automation: Scheduling
pg_dumpjobs with Task Scheduler for consistent disaster recovery. - ETL Orchestration: Running imports/exports and staging transformations as part of a nightly pipeline.
- Local Dev Reset: Recreating and reseeding a local database quickly when developers switch branches.
Important Considerations
- Password Security: Avoid hard-coding passwords in
.batfiles. EvenPGPASSWORDis still a plain-text secret in your script or console session. Preferpgpass.conf/PGPASSFILEwith tight NTFS permissions for unattended jobs. - Host Access (
pg_hba.conf): If you seeno pg_hba.conf entry for host, the server is refusing your connection. On Windows,pg_hba.confis in the PostgreSQL data directory (commonlyC:\Program Files\PostgreSQL\<version>\data\pg_hba.conf, but it can vary by installation). Update rules and reload/restart PostgreSQL. - Reliable Exit Codes: Use
-v ON_ERROR_STOP=1for automation. Without it, some SQL errors will print messages but still return a success exit code, which breaks%errorlevel%checks.
Conclusion
Connecting to PostgreSQL from a Batch script enables repeatable administrative operations: running queries, generating reports, and executing migration bundles as part of scheduled maintenance. With psql.exe and careful credential handling, simple .bat files can safely integrate PostgreSQL tasks into Windows automation workflows.