PostgreSQL 13 + Python 3.7.9 + plpython3u: 'psql: server closed the connection unexepectedly.' + 'The application has lost the database connection.'
Asked Answered
P

4

2

I have added all of the details I could find, with all of the links, and there is no way to get plpython3u to work on Windows in PostgreSQL 13, it seems.

OLD, since the accepted answer shows that v3.7.0 solves it: Better do not read through this long question and rather just jump to the answer: not to use Windows PostgreSQL when you need plpython3u. This question has been opened long enough, no solution in sight.

Perhaps a higher PostgreSQL version for Windows will solve this, then please answer.


Spin-off

This is a spin-off from

Can't “install” plpython3u - postgresql and all of its comments

and from

PosgreSQL 11 lost connection when i'm trying to create function with plpython3u [WIN10, pgAdmin4 3.5].

Steps of errors and solutions up to now

I have taken these steps which were totally scattered across Stack Overflow:

Step 0

If you run a sql that uses the language plpython3u without it being installed, you get

ERROR: language "plpython3u" does not exist HINT: Use CREATE EXTENSION to load the language into the database.

SQL state: 42704

Related:

Step 1

At error

ERROR: could not load library "C:/Program Files (x86)/PostgreSQL/13/lib/plpython3u.dll": The specified module could not be found.

SQL state: 58P01

look up C:\Program Files\PostgreSQL\13\doc\installation-notes.html to find the needed Python version to be installed for the installed PostgreSQL version.

PostgreSQL 13

Installation Notes

Welcome to the PostgreSQL 13 Installation Wizard.

Procedural Languages

The procedural languages pl/Perl, pl/Python and pl/Tcl are included in this distribution of PostgreSQL. The server has been built using the LanguagePack community distributions of those language interpreters. To use any of the these languages from within PostgreSQL, download and install the appropriate interpreters and ensure they are included in the PATH variable under which the database server will be started. The versions used are shown below - newer minor (bugfix) releases may also work, but have not been tested:

Perl 5.26
Python 3.7
Tcl 8.6

enter image description here

Thus, Python 3.7 is needed.

Credits go to:

Related:

Step 2

Install Python version using the webinstaller of Python Releases for Windows

The most recent sub-version 3.7.10 does not have any files in the list of stable releases and I am too lazy to install Python from source on Windows. The source code of v3.7.10 is available here Looking for a specific release?, for anyone who wants to try):

Python 3.7.10 - Feb. 15, 2021

Note that Python 3.7.10 cannot be used on Windows XP or earlier.

No files for this release.

enter image description here

Explanation copied from How to build Python 3.4.6 from source?

The Python 3.7 branch is in security fixes only mode. This means that only security fixes will be accepted on this branch, no more non-critical bug fixes. New releases on this branch are source-only, no binaries will be provided.

See the official announcement.

If you really need a python 3.7.10 binary for windows, you will have to compile it yourself.

Cannot install plpython for postgres 12 recommends to install a specific version from source:

you want to use a specific python version > use source and compile it

Again, since I am lazy, I take the most recent stable release of 3.7, which is sub-version 3.7.9, and this should be no problem following the remark, as you seem to be free to choose the sub-version:

Try version python-3.4.0.amd64 for windows 64bit or other versions from this Python 3.4.0 downloads Link

From: could not load library plpython3.dll

As I said, I am too lazy to take the effort of compiling the binaries of v3.7.10 on Windows when v3.7.9 is available, thus:

Python 3.7.9 - Aug. 17, 2020

Note that Python 3.7.9 cannot be used on Windows XP or earlier.

Download Windows help file
Download Windows x86-64 embeddable zip file
Download Windows x86-64 executable installer
Download Windows x86-64 web-based installer
Download Windows x86 embeddable zip file
Download Windows x86 executable installer
Download Windows x86 web-based installer

enter image description here

I install "Download Windows x86-64 web-based installer" (side-note: you cannot change the installation path, they seem to force you to use this; to reach it quickly, in Windows Explorer, type in the path %appdata% --> go to parent folder "appdata" --> then to "local" --> "programs" --> "python" to quickly get there) and check the box for adding the PATH variables as well.

You will have a new entry in your user environment variable "PATH" and you may check this, but you do not need to:

C:\Users\MY_USER\AppData\Local\Programs\Python\Python37\Scripts\

and

C:\Users\MY_USER\AppData\Local\Programs\Python\Python37\

enter image description here

Credits go to:

Step 3

When executing

CREATE EXTENSION plpython3u;

in the query tool of PostgreSQL pgAdmin4, I get the error:

could not load library "C:/Program Files/PostgreSQL/13/lib/plpython3u.dll": The specified module could not be found

Go to your Python 3.7 installation folder, in my case

C:\Users\MY_USER\AppData\Local\Programs\Python\Python37

and copy "python37.dll" from there to

C:\Windows\System32

by confirming that you have admin rights.

Now execute again and it will work:

CREATE EXTENSION plpython3u;

Credits go to:

Related questions:

Step 4 (optional)

SELECT * FROM pg_extension;

Output:

old    | extname       | extowner | extrelocatable | extversion | extversion | extconfig | extcondition
"13428"| "plpgsql"     | "10"     | "11"           | false      | "1.0"      | [null]    | [null]
"16776"| "plpython3u"  | "10"     | "11"           | false      | "1.0"      | [null]    | [null]

enter image description here

And another check with:

SELECT * FROM pg_language;

Output:

  lanname   | lanowner | lanispl | lanpltrusted | lanplcallfoid | laninline | lanvalidator | lanacl
------------+----------+---------+--------------+---------------+-----------+--------------+--------
 internal   |       10 | f       | f            |             0 |         0 |         2246 |
 c          |       10 | f       | f            |             0 |         0 |         2247 |
 sql        |       10 | f       | t            |             0 |         0 |         2248 |
 plpgsql    |       10 | t       | t            |         12279 |     12280 |        12281 |
 plpython3u |       10 | t       | f            |         40963 |     40964 |        40965 |
(5 rows)

Now the available extensions (that is, all possible extensions that can be installed) also show installed_version = 1.0 for the plpython3u extension:

SELECT * FROM pg_available_extensions WHERE name LIKE '%python%' ORDER BY name;

Output:

enter image description here

or the output when running the same in psql:

    name    | default_version | installed_version |                  comment
------------+-----------------+-------------------+-------------------------------------------
 plpython3u | 1.0             | 1.0               | PL/Python3U untrusted procedural language
(1 Zeile)

We see here probably one of the main reasons why there is no recent image that offers plpython extensions: PL/Python3U untrusted procedural language.

And another query which shows the same:

SELECT * FROM pg_pltemplate;

Output:

  tmplname  | tmpltrusted | tmpldbacreate |      tmplhandler       |        tmplinline        |    tmplvalidator    |    tmpllibrary    | tmplacl
------------+-------------+---------------+------------------------+--------------------------+---------------------+-------------------+---------
 plpgsql    | t           | t             | plpgsql_call_handler   | plpgsql_inline_handler   | plpgsql_validator   | $libdir/plpgsql   |
 pltcl      | t           | t             | pltcl_call_handler     |                          |                     | $libdir/pltcl     |
 pltclu     | f           | f             | pltclu_call_handler    |                          |                     | $libdir/pltcl     |
 plperl     | t           | t             | plperl_call_handler    | plperl_inline_handler    | plperl_validator    | $libdir/plperl    |
 plperlu    | f           | f             | plperlu_call_handler   | plperlu_inline_handler   | plperlu_validator   | $libdir/plperl    |
 plpythonu  | f           | f             | plpython_call_handler  | plpython_inline_handler  | plpython_validator  | $libdir/plpython2 |
 plpython2u | f           | f             | plpython2_call_handler | plpython2_inline_handler | plpython2_validator | $libdir/plpython2 |
 plpython3u | f           | f             | plpython3_call_handler | plpython3_inline_handler | plpython3_validator | $libdir/plpython3 |
(8 rows)

For the plpython extensions, we see False in the tmpltrusted column and False in the tmpdbacreate column, while the three trusted extensions "plpgsql", "pltcl" and "plperl" are True in the same columns.

Credits go to:

Step 5

Now run a general test query like this:

CREATE OR REPLACE FUNCTION return_version()
  RETURNS VARCHAR
AS $$
    import sys
    return sys.version
$$ LANGUAGE plpython3u;

If this worked, you would be able to run the SQL query SELECT return_version() and get

Output:

CREATE FUNCTION

Test:

postgres=# SELECT return_version();
              return_version
------------------------------------------
 3.8.10 (default, Jun  2 2021, 10:49:15) +
 [GCC 9.4.0]
(1 row)

Of course, we cannot see this, elsewise the question would be solved. It would be 3.7.9 in this case, I used the Linux installation where plpython3u works, see the Linux hint in the answer.


Side note: a more complicated test with loaded modules

Normally, you can ignore this second test and stop at the return_version() function test.

Of course, if the creating the function return_version() fails, the following will also fail. This second test is just to check whether you can also load modules as soon as plpython3u can be used. You will need to install the needed Python packages which must be compatible with Python 3.7, in this case. It seems that one has to use pip and not conda since Python was meant to be downloaded from the official website. To avoid dependency conflicts, it might be good to use Poetry as a package manager (similar to conda, just for pip).

When executing this PostgreSQL query of Machine Learning in PostgreSQL Part 1: Kmeans clustering, using the language plpython3u (the needed packages "pandas" and "sklearn" are installed in the base environment of Python3.7, that is, no virtual environment is used to avoid the unsolved Can python venv be used with plpython3u for postgresql?, which is absolutely not what I expected from a standard setter like PostgreSQL):

CREATE OR replace FUNCTION kmeans(input_table text, columns text[], clus_num int) RETURNS bytea AS
 
$$
 
from pandas import DataFrame
from sklearn.cluster import KMeans
from pickle import dumps
 
all_columns = ",".join(columns)
if all_columns == "":
    all_columns = "*"
 
rv = plpy.execute('SELECT %s FROM %s;' % (all_columns, plpy.quote_ident(input_table)))
 
frame = []
 
for i in rv:
    frame.append(i)
df = DataFrame(frame).astype('float')
kmeans = KMeans(n_clusters=clus_num, random_state=0).fit(df._get_numeric_data())
return dumps(kmeans)
 
$$ LANGUAGE plpython3u;

End of the sidenote


Any test query using LANGUAGE plpython3u will cause the error:

ERROR: server closed the connection unexpectedly

This probably means the server terminated abnormally before or while processing the request.

enter image description here

and when I run another query after this, it runs, but before clicking "Continue", I get:

The application has lost the database connection.

- If the connection was idle, it may have been forcibly disconnected.
- The application server or database server may have been restarted.
- The user session may have timed out.

Do you want to continue and establish a new session?

enter image description here

This might be solved by the thread PosgreSQL 11 lost connection when i'm trying to create function with plpython3u [WIN10, pgAdmin4 3.5]. Such an answer shows that the sub-version of v3.7.9 or v3.7.10 or another could indeed matter! Do I need to install version 3.7.10 from source just to have the most recent version?

I do not want to take the effort of installing Python 3.7.10 from source just to check this out. Who says that changing from v3.6.5 to v3.6.7 has really solved it in the link above, and that it was not rather something happening just because of a new install?

I could also try out v3.7.0.

Python 3.7.0 - June 27, 2018

Note that Python 3.7.0 cannot be used on Windows XP or earlier.

Download Windows help file
Download Windows x86-64 embeddable zip file
Download Windows x86-64 executable installer
Download Windows x86-64 web-based installer
Download Windows x86 embeddable zip file
Download Windows x86 executable installer
Download Windows x86 web-based installer

enter image description here

But since version v3.6.7 once seems to have worked, I do not see a reason why I should invest into this.

Credits go to:

Related:

Windows installation with EDB and Stack Builder

EDB and Stack Builder is the installation method that is recommended by the PostgreSQL website. I found this at Cannot install plpython for postgres 12 (a thread which just deals with not being able to create the extension at all and therefore cannot help out). I installed PostgreSQL 10 since plpython3u works with that in the timescaleDB Linux container (see "Docker" below) and my hope was that this lower PostgreSQL version would solve it. But with this official installation method, using EDB and then the Stack Builder for the additional "pl/python language pack", I still get the same error.

Question

Which sub-version of Python 3.7 (v3.7.10, v3.7.0, or another; perhaps my v3.7.9 is also already right since plpython extension could be created with that) is surely working together with PostgreSQL13, and how would this have to be found out if not just by testing around? And if choosing the right Python sub-version is not the issue here (which is more likely), how else can I fix the Step 5 errors that pop up from using the LANGUAGE plpython3u:

ERROR: server closed the connection unexpectedly

This probably means the server terminated abnormally before or while processing the request.

(which is a question at psql: server closed the connection unexepectedly but is not focused on this Python extension problem)

and

The application has lost the database connection.

(which is a question at PosgreSQL 11 lost connection when i'm trying to create function with plpython3u [WIN10, pgAdmin4 3.5] but would mean installing v3.7.10 from source only to have the most recent sub-version, and I try to find out the right sub-version or another trick to get it run before doing so)

Polarity answered 5/6, 2021 at 18:18 Comment(1)
and copy "python37.dll" from there to C:\Windows\System32 by confirming that you have admin rights. This is really important!Whereunto
G
3

Workaround for Windows and Postgres 13

I was finally able to make it work with Python 3.7.0. If anybody is looking for a solution they can install Python 3.7.0. Of course any new introduced in subsequent versions will not be available. I had to refactor my code to remove f-strings. Its a small trade-off for the convenience of using Python in stored procedures and functions.

PostgresSQL version: 13.4-2

Python version download link https://www.python.org/ftp/python/3.7.0/python-3.7.0-amd64.exe

Garmon answered 1/11, 2021 at 8:41 Comment(2)
So nice you found out about this, I should vote twice for the invested nerves. Funny. I have skipped that 3.7.0, saying: "I could also try out v3.7.0. ... But since version v3.6.7 once seems to have worked, I do not see a reason why I should invest into this." Well, sometimes you should rather not guess too much but just try. :)Polarity
Thanks for your detailed post. That actually helped a lot in understanding and learning about PGSQL extensions and languages.Garmon
P
0

Workaround: plpython3u does work on Linux! So use it on Linux.

This last paragraph is not part of the question and just lists some steps on Linux as an alternative in the meantime when the Windows plpython3u installation does not work.

Docker:

  • On Windows, install Docker Desktop (recommended) or use Docker on WSL2. Elsewise, just install Docker directly on Linux.

  • A typical postgres Docker setup that you can easily change to a more recent version can be found at Docker PostgreSQL 9.6 - installing extension plpython3u (clashing with quantile extension).

  • Docker has the problem that you need extra tricks so that the database is saved even if you remove the container, like:

    • pg_dump / pb_restore / psql ... > / psql... < to backup on the local Linux disk and then restore the database from a mounted volume of your choice, or
    • a Web Server to save your db permanently.
  • You might also catch a first glimpse from threads like PostgreSQL on Docker: How to install and run python dependencies under plpython3u?, to start with, or take the official postgres image using docker-compose guide as the postgres base and extend it by plpython3.

  • One main trick in one container that failed to use plpython3u was to add SymLinks instead of hardcoded installation paths, see Add plpython3 Extension to Postgres/timescaledb Alpine Docker Image. This worked for me. Using this alpine TimescaleDB Dockerfile, I could use plpython3u! Caveat of this old Python 3.6 version in this container: I could not install the needed packages for the kmeans test above which are pandas, scikit-learn and pickle, neither with pip nor with Poetry. And it seems that this alpine container with Python 3.6 does not support pandas while Python 3.7 would: Installing pandas in docker Alpine. If the needed packages cannot be installed, plpython3u is of no value in this docker container. That is why you should use a more recent Docker image of PostgreSQL (or for example timescaleDB) so that you do not run into such legacy issues of Python 3.6 dependencies.

Standalone

You might also try an installation on standalone Linux when saving the data permanently and locally gets more important.

Guessed answer (ALL WRONG; SEE ACCEPTED ANSWER INSTEAD)

With WSL, WSL2 and Docker Desktop, since years, Linux has become a friend of Windows. Windows seems to encourage this. The shift towards postgreSQL on Linux is probably the reason for the poor Windows support of plpython3u, recently. In the meantime, you should install it on Linux (standalone or in a Docker container).

But what might be wrong wrong with the Windows installation?

  • As already said, Windows does not get the PostgreSQL attention that Linux gets. I guess that on Windows, I have to install PostgreSQL from source, together with the plpython extension and its dependencies, to get plpython3u to run properly.

  • Perhaps, the normal Windows installer also does not support plpython just because of a mere technical detail: The query in the question above shows: PL/Python3U untrusted procedural language. It may not be allowed on a usual production system. For example, the Webserver service TimescaleForge (timescaleDB, based on PostgreSQL) have answered that they do not offer any plpython extension because of the security risk, even if the client asks for it. They rather offer trusted extensions for clear problems, not a full language that can do anything and is therefore a security risk. Obviously, you can use untrusted extensions when building from source, as TimescaleForge do with their own extensions.

  • There might be the need to set a PATH variable as in the answer at “Module not found” when importing a Python package within a plpython3u procedure.

  • Perhaps on Windows, the default version of Python must be changed somewhere before installation? This is just a very vague guess from a Linux installation using make, with Python settings in /etc/make.conf

  • And finally:

It seems possible that plpython3u will run in PostgreSQL on Windows when the same installation tricks are used as have been used in this Dockerfile of the mentioned link above, Add plpython3 Extension to Postgres/timescaledb Alpine Docker Image, where plpython3u works:

RUN set -ex \
    && apk add --no-cache --virtual .plpython3-deps --repository http://nl.alpinelinux.org/alpine/edge/testing \
    postgresql-plpython3 \
    && ln -s /usr/lib/postgresql/plpython3.so /usr/local/lib/postgresql/plpython3.so \
    && ln -s /usr/share/postgresql/extension/plpython3u.control /usr/local/share/postgresql/extension/plpython3u.control \
    && ln -s /usr/share/postgresql/extension/plpython3u--1.0.sql /usr/local/share/postgresql/extension/plpython3u--1.0.sql \
    && ln -s /usr/share/postgresql/extension/plpython3u--unpackaged--1.0.sql /usr/local/share/postgresql/extension/plpython3u--unpackaged--1.0.sql

Thus, .plpython3-deps and postgresql-plpython3 must be installed and the SymLinks must be added.

Perhaps, such SymLinks are already the main trick on Windows as well, though I could not get it to work with SymLinks in a quick test, see PostgreSQL on Windows: get “plpython3u” extension to run with the help of SymLinks? which was rightfully deleted since the solution is much easier, see the other answer.

Polarity answered 1/9, 2021 at 8:36 Comment(0)
S
0

Although I have this answer on another post, I find value to giving full of it here instead of just linking, plus a few edits here and there expanding it a bit.


I was trying the same. Though I am no expert and my errors were a bit different, here are a few things to check:

step-1

  • under share\extension\, there should be plpython3u.control and plpython3u--1.0.sql to be able to do CREATE EXTENSION plpython3u;
  • ensure you are not having any typo in the command above.

step-2

  • under lib\, there should be a plpython3.dll. This one is possibly created after the above step.
  • make sure lib\ is in your PATH.

step-3

  • without PYTHONHOME, the server crashes.
  • PYTHONHOME should be set in either system/user environment, or should be set before the server start. It seems the version is not as much important as having this name set. plpython3.dll seems to look for a python39.dll but I could use it with a 3.8 installation.
  • python version difference should raise an error only when you try to use specific functionality to that version. install another new/old version if you need that. just don't forget about PYTHONHOME.

I used a zipped version of Postgres, so the following is my way to run the server.

set PATH=%PATH%;d:\pgsql\bin\;d:\pgsql\lib\
set PYTHONHOME=c:\DevTools\Python\Python38
pg_ctl -D d:\pgsql\pgdata -l logfile start

PS: I don't allow the python installer set things in the environment as I use many versions and no version manager. So it usually leads me to have these kinds of errors, but they make nice mental exercises here and there :)

Sicanian answered 17/5, 2022 at 9:55 Comment(0)
M
0

This has worked for me (Windows 10, Postgres 13.11 ). I assume this also works for PostgreSQL 11, 12, 14 and 15.

Install Postgres from the EDB download site: https://www.enterprisedb.com/downloads/postgres-postgresql-downloads Make sure to include the Language Pack in the Stackbuilder installer. At installation time, run the Language Pack installer. It also installs the required Python version.

After installing PostgreSQL, you can check the required Python version in C:/Program Files/PostgreSQL/13/doc/installation-notes.html (answer: Python 3.7; the subversion does not matter)

To tell the Python interpreter where to find Python: Edit the Windows Environment Variables and in System Variables add a new variable PYTHONHOME=C:\edb\languagepack\v1\Python-3.7 To be on the safe side, I also deleted all Python related entries in both the User and Systems variables PATH, but this might be an overkill.

Open Cmd.exe with Administrator rights and copy the EDB python37.dll to system32:

    copy C:\edb\languagepack\v1\Python-3.7\python37.dll c:\windows\system32

Restart the PC. Open PgAdmin4 and open a Query Tool window to execute "create extension plpython3u;". Check with "SELECT * FROM pg_extension;"

Minoru answered 25/5, 2023 at 18:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.