如何为Ubuntu 18.04上Postgres 10的PL/Python升级至Python 3.8.0
Got it, let's break down why your PL/Python is still clinging to Python 3.5.2 even after setting up Python 3.8 via pyenv. The key thing to understand here is: PL/Python isn't just picking up the Python in your PATH—it's a compiled extension that links directly to a specific Python shared library when PostgreSQL was built. The default Ubuntu packages for PostgreSQL 10 bind plpython3u to the system's Python 3.5, so changing environment variables like PYTHONPATH won't swap out the underlying runtime.
Here's how to fix this:
Step 1: Confirm the Current Linked Python Library
First, verify exactly which Python version your PL/Python extension is tied to. Run these commands as root or with sudo:
# Get PostgreSQL's library directory PG_LIB=$(pg_config --pkglibdir) # Check the linked Python library ldd $PG_LIB/plpython3.so | grep libpython
You'll see output pointing to libpython3.5m.so or similar, confirming it's using the system's Python 3.5.
Step 2: Compile PL/Python3 for Python 3.8
We need to recompile the PL/Python3 extension to link against your pyenv-installed Python 3.8. Here's how:
1. Install Dependencies
First, install the tools and dev packages needed for compilation:
sudo apt-get update sudo apt-get install postgresql-server-dev-10 python3.8-dev build-essential
2. Get PostgreSQL 10 Source Code
We need the exact source code matching your PostgreSQL 10 version (check with psql -V—e.g., 10.23). Download it from the official repo:
# Replace 10.23 with your exact PostgreSQL 10 version wget https://ftp.postgresql.org/pub/source/v10.23/postgresql-10.23.tar.gz tar xzf postgresql-10.23.tar.gz cd postgresql-10.23/src/pl/plpython
3. Compile the Extension for Python 3.8
Point the compilation to your pyenv Python 3.8 binary, then build:
# Replace with your pyenv Python 3.8 path (find it with `which python3.8` as postgres user) PYTHON=/var/lib/postgresql/.pyenv/versions/3.8.0/bin/python3.8 make
4. Replace the Existing Extension File
First back up the original file (critical for rollbacks):
sudo cp $PG_LIB/plpython3.so $PG_LIB/plpython3.so.backup sudo cp plpython3.so $PG_LIB/
Step 3: Configure Library Path & Restart PostgreSQL
Since your Python 3.8 is installed via pyenv, PostgreSQL needs to find its shared library. Edit the PostgreSQL environment file:
sudo nano /etc/postgresql/10/main/environment
Add this line (replace with your pyenv Python 3.8's lib directory):
LD_LIBRARY_PATH='/var/lib/postgresql/.pyenv/versions/3.8.0/lib'
Then restart PostgreSQL to apply changes:
sudo systemctl restart postgresql@10-main
Step 4: Verify the Fix
Log into PostgreSQL and re-test your function:
CREATE OR REPLACE FUNCTION ptest () RETURNS text AS $$ import sys return sys.version $$ LANGUAGE plpython3u; SELECT ptest();
You should now see the Python 3.8.0 version string in the result!
Important Notes
- Always back up the original
plpython3.sobefore replacing it—if something breaks, you can restore it withsudo cp $PG_LIB/plpython3.so.backup $PG_LIB/plpython3.soand restart PostgreSQL. - If you update PostgreSQL later, you'll need to recompile the PL/Python extension again, since package updates will overwrite the custom-compiled file.
内容的提问来源于stack exchange,提问作者Xinzhou Liu

