Question
I am trying to install psycopg2 on RHEL 5.5 with:
sudo pip install psycopg2
but the installation fails with this error:
Error: pg_config executable not found.
Please add the directory containing pg_config to the PATH,
or specify the full executable path with the option:
python setup.py build_ext --pg-config /path/to/pg_config build ...
However, pg_config appears to be available in my shell:
which pg_config
# /usr/pgsql-9.1/bin/pg_config
I also tried specifying /usr/pgsql-9.1/bin/pg_config in setup.cfg, but then received:
Error: Unable to find 'pg_config' file in '/usr/pgsql-9.1/bin/'
Why can psycopg2 not find pg_config when it exists, and how can I install it correctly?
Short Answer
You will learn what pg_config does during a psycopg2 source installation, why your interactive shell's PATH can differ from sudo's environment, and how to pass a correct executable path to the build.
Concept
psycopg2 is a Python adapter for PostgreSQL. When it is installed from source, it compiles native C code that must link against PostgreSQL client libraries.
pg_config is a PostgreSQL program that reports where those libraries and header files are installed. For example, it can provide locations for:
- C header files such as
libpq-fe.h - PostgreSQL client libraries such as
libpq - PostgreSQL build and version information
During installation, psycopg2 runs pg_config as an executable. It is not enough for a file to exist: the installation process must be able to locate and execute that exact file.
A frequent source of confusion is that this works in your normal shell:
which pg_config
but the package build is run through sudo. sudo may replace or restrict PATH for security. As a result, root's environment may not include /usr/pgsql-9.1/bin, even though your user's environment does.
Mental Model
Think of PATH as a list of drawers that the shell searches for a tool.
When you type pg_config, your shell checks each drawer listed in your PATH until it finds the tool. When you run sudo pip install ..., the installation may use a different person’s drawer list: root’s PATH.
The tool can be sitting safely in /usr/pgsql-9.1/bin, but if root is not told to search that drawer, the build reports that it cannot find it.
Syntax and Examples
The PATH variable contains directories, separated by colons. It should contain the directory that holds a command, not the command itself.
export PATH="/usr/pgsql-9.1/bin:$PATH"
Verify both that the file exists and that it can run:
ls -l /usr/pgsql-9.1/bin/pg_config
/usr/pgsql-9.1/bin/pg_config --version
To make that directory available only for one installation command:
sudo env PATH="/usr/pgsql-9.1/bin:$PATH" pip install psycopg2
The env command sets PATH for the command launched by sudo. This avoids relying on sudo to preserve your normal shell environment.
If building from a source checkout or source archive, pass the full file path—not merely its directory—to the build option:
python setup.py build_ext --pg-config=/usr/pgsql-9.1/bin/pg_config build
A setup.cfg configuration uses the same idea:
Step by Step Execution
Consider this command:
sudo env PATH="/usr/pgsql-9.1/bin:$PATH" pip install psycopg2
- Your current shell expands
$PATHto its current list of directories. envcreates aPATHbeginning with/usr/pgsql-9.1/bin.sudorunspipwith that explicitly supplied environment value.pipdownloads or reads thepsycopg2source distribution.- The build runs
pg_configfrom/usr/pgsql-9.1/bin/pg_config. pg_configtells the build where PostgreSQL headers and libraries are installed.psycopg2compiles its extension, assuming the needed compiler and PostgreSQL development files are installed.
Useful diagnostics compare the two environments:
command -v pg_config
sudo command -v pg_config
PATH= -v pg_config
Real World Use Cases
Native Python packages commonly need external tools during installation.
- Database adapters:
psycopg2uses PostgreSQL development information frompg_config. - Image packages: packages may need C compilers and image-library headers.
- Cryptography and networking packages: builds can require OpenSSL headers and libraries.
- CI pipelines: a build agent may have the correct tools installed, but fail because its non-interactive
PATHis different. - Containers: a Docker build can install runtime libraries but omit development packages, causing source builds to fail.
The general debugging pattern is: check the executable path, check which user runs the build, and check that the executable can run in that environment.
Real Codebase Usage
In real projects, developers usually avoid depending on an accidentally configured interactive shell.
Common practices include:
-
Use explicit paths in build scripts when a nonstandard PostgreSQL installation is required.
PG_CONFIG=/usr/pgsql-9.1/bin/pg_config export PATH="$(dirname "$PG_CONFIG"):$PATH" pip install psycopg2 -
Install development dependencies in provisioning scripts before installing Python requirements. On RPM-based systems, this commonly includes PostgreSQL development packages and a compiler toolchain.
-
Keep runtime and build dependencies separate. An application may need only PostgreSQL client libraries at runtime, while compiling
psycopg2also requires headers andpg_config. -
Make CI environments reproducible. Store required system-package installation and environment configuration in CI configuration or container build files instead of relying on a developer’s shell profile.
-
Avoid unnecessary
sudo pip. Installing Python packages into a virtual environment generally avoids system-wide permission issues and reduces differences between user and root environments.
Common Mistakes
Adding the executable instead of its directory to PATH
Incorrect:
export PATH="/usr/pgsql-9.1/bin/pg_config:$PATH"
Correct:
export PATH="/usr/pgsql-9.1/bin:$PATH"
PATH contains directories only.
Giving setup.cfg a directory rather than an executable
Incorrect:
[build_ext]
pg_config = /usr/pgsql-9.1/bin/
Correct:
[build_ext]
pg_config = /usr/pgsql-9.1/bin/pg_config
The option expects the full path to the pg_config program.
Checking only the normal user environment
This can succeed:
pg_config
Comparisons
| Approach | When to use it | Key point |
|---|---|---|
Add a directory to PATH | pg_config is installed in a nonstandard location | Add /usr/pgsql-9.1/bin, not the file itself. |
Pass --pg-config=/full/path | Building directly from a source tree | Most explicit option for that build. |
Set pg_config in setup.cfg | Rebuilding the same source package repeatedly | The value must be the full executable path. |
Use sudo env PATH=... | sudo has a restricted PATH | Supplies the required path only for one command. |
| Use a virtual environment |
Cheat Sheet
# Check whether the executable exists and runs
ls -l /usr/pgsql-9.1/bin/pg_config
/usr/pgsql-9.1/bin/pg_config --version
# Check the current user versus the sudo environment
command -v pg_config
sudo command -v pg_config
# Install with an explicit PATH for this command
sudo env PATH="/usr/pgsql-9.1/bin:$PATH" pip install psycopg2
# Build source using an explicit executable path
python setup.py build_ext --pg-config=/usr/pgsql-9.1/bin/pg_config build
Rules:
PATHcontains directories, separated by:.pg_configsettings need the full executable path.- The user running the build must be able to find and execute
pg_config. - If discovery succeeds but compilation fails, check PostgreSQL development headers and compiler dependencies.
FAQ
Why does which pg_config work but pip install fail?
The installation may run under sudo, a service account, a CI runner, or another environment with a different PATH.
Should I add pg_config itself to PATH?
No. Add its containing directory, such as /usr/pgsql-9.1/bin.
What should the pg_config value in setup.cfg be?
Use the full executable filename:
pg_config = /usr/pgsql-9.1/bin/pg_config
How can I check whether sudo can find pg_config?
Run:
sudo command -v pg_config
If it prints nothing, use an explicit PATH for the install command or configure the root environment appropriately.
Why does psycopg2 need pg_config?
A source build needs PostgreSQL’s client header and library locations so it can compile and link its native extension.
Mini Project
Description
Create a small shell diagnostic script that checks whether pg_config is visible to both your current user and the environment used by sudo. This mirrors a common deployment and CI troubleshooting task.
Goal
Produce a clear report showing whether pg_config exists, can execute, and is available when commands run through sudo.
Requirements
- Accept the pg_config directory as an optional first argument.
Keep learning
Related questions
@staticmethod vs @classmethod in Python Explained
Learn the difference between @staticmethod and @classmethod in Python with clear examples, use cases, mistakes, and a mini project.
Add Rows to a Pandas DataFrame in Python
Learn how to add rows to a Pandas DataFrame, why repeated row appends are slow, and when to use loc, concat, or record lists.
Call a Function by Name in a Python Module
Learn how to call a function by name in a Python module using strings, getattr, and safe patterns for dynamic function dispatch.