System-wide installation of Python packages in 2025

I find myself in need of installing a Python package system-wide to make it available for PostgreSQL’s plpython3u procedural language. After all these years going to pains not to do this and use virtual environments instead, I realized I actually don’t know how to do this the right way. :person_facepalming: :grin:

  • OS is Debian.
  • The package is not available for installation with apt.
  • It is a server, so no worries about multi-user installs and disturbing other users.
  • I see that PostgreSQL understands the PYTHONPATH variable, so ideally I would install it somewhere separate from the “real” system packages to keep it nicely under control.

Any pointers would be greatly appreciated.

Spin up a docker container with some test DB data, and just go for it, see what happens.

Or is the issue installing pip into the system Python from apt?

Is it possible to tell PostgreSQL’s plpython3u which Python interpreter should be used exactly? How does this run Python? Is the path to the Python interpreter hard-coded? Does it simply run python3? Maybe setting the PATH environment variable to point to the bin directory of a custom-made Python virtual environment when starting Postgres could be helpful.

3 Likes

I would install the code into /usr/local/… tree and set PYTHONPATH for postgresql to include that /usr/local/… path.

You should be able to set the PYTHONPATH in a systemd unit override for the postgresql service.

Getting pip to put stuff there requires --break-system-packages, which, I imagine, is what prompted the question whether that is really the right way.

If it is possible to set the python executable, I’d use a venv, per sinoroc’s suggestion. If not, I’d say this use-case is exactly why the --break-system-packages flag exists.

1 Like

Looks like it might be possible to activate a virtual environment from within a PL/Python function. Here is one example of an article showing such a technique, but there plenty are other resources: https://www.enterprisedb.com/blog/using-virtual-environment-plpython3-postgresql. Using/activating a virtual environment is still probably the safest way to deal with additional Python dependencies, that is what I would try to focus my efforts on.

So long as the package being install does not update abd system package that is a reasonable thibg to do.

Otherwise I would install in a venv and then copy the files in /usr/local/…

Don’t think it’s worth battling to get postgresql to use a venv.