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

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

我已经添加了我能找到的所有详细信息,以及所有 links,但无法让 plpython3u 在 Windows 中工作PostgreSQL 13,好像。

OLD,因为接受的答案显示 v3.7.0 解决了它: 最好不要通读这个冗长的问题,而是直接跳到答案:当您需要 plpython3u 时,不要使用 Windows PostgreSQL。这个问题打开的时间够长了,看不到答案。

也许 Windows 的更高 PostgreSQL 版本可以解决这个问题,请回答。


分拆

这是

的衍生产品

Can't “install” plpython3u - postgresql 及其所有评论

来自

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

到目前为止的错误步骤和解决方法

我已经采取了这些完全分散在 Stack Overflow 中的步骤:

第 0 步

如果你 运行 sql 使用语言 plpython3u 而没有安装它,你会得到

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

SQL state: 42704

相关:

步骤 1

出错

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

SQL state: 58P01

查找 C:\Program Files\PostgreSQL\doc\installation-notes.html 以找到为已安装的 PostgreSQL 版本安装所需的 Python 版本。

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

因此,Python 3.7 是必需的。

学分转到:

相关:

步骤 2

使用 Python Releases for Windows

的网络安装程序安装 Python 版本

最新的子版本 3.7.10 在稳定版本列表中没有任何文件,我懒得从 Windows 上的源代码安装 Python。 v3.7.10 的源代码在这里Looking for a specific release?,任何想尝试的人都可以得到):

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.

解释复制自 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建议从源安装特定版本:

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

再说一次,因为我比较懒,所以我拿的是3.7最新的稳定版,也就是3.7.9的子版本,按备注应该没问题,你好像可以自由选择子版本:

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

发件人:

正如我所说,当 v3.7.9 可用时,我懒得在 Windows 上编译 v3.7.10 的二进制文件,因此:

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

我安装“下载 Windows x86-64 基于 web 的安装程序”(旁注:您不能更改安装路径,他们似乎强迫您使用它;要快速到达它,请在 Windows Explorer,输入路径 %appdata% --> 进入父文件夹“appdata” --> 然后到“local” --> “programs” --> “python” 快速获取那里)并选中用于添加 PATH 变量的框。

您的用户环境变量“PATH”中将有一个新条目,您可以检查它,但您不需要:

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

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

学分转到:

步骤 3

执行时

CREATE EXTENSION plpython3u;

在PostgreSQLpgAdmin4的查询工具中,出现错误:

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

转到您的 Python 3.7 安装文件夹,在我的例子中

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

并将“python37.dll”从那里复制到

C:\Windows\System32

确认您拥有管理员权限。

现在再次执行就可以了:

CREATE EXTENSION plpython3u;

学分转到:

相关问题:

第 4 步(可选)

SELECT * FROM pg_extension;

输出:

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]

再检查一次:

SELECT * FROM pg_language;

输出:

  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)

现在可用的扩展(即可以安装的所有可能的扩展)也显示 plpython3u 扩展的 installed_version = 1.0:

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

输出:

或者当运行在psql中相同时的输出:

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

我们在这里看到可能没有提供 plpython 扩展的最新图像的主要原因之一:PL/Python3U untrusted procedural language.

另一个显示相同的查询:

SELECT * FROM pg_pltemplate;

输出:

  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)

对于 plpython 扩展,我们在 tmpltrusted 列中看到 False,在 tmpdbacreate 列中看到 False,而三个受信任的扩展“plpgsql”、“pltcl”和“plperl”在同一列中 True

学分转到:

步骤 5

现在 运行 像这样的一般测试查询:

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

如果这有效,您将能够 运行 SQL 查询 SELECT return_version() 并获得

输出:

CREATE FUNCTION

测试:

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

当然不能看到这个,不然问题就解决了。在这种情况下它将是 3.7.9,我使用了 plpython3u 工作的 Linux 安装,请参阅答案中的 Linux 提示。


旁注:加载模块的更复杂测试

通常情况下,您可以忽略这第二个测试并在return_version()功能测试处停止。

当然,如果创建函数return_version()失败,下面的也会失败。这第二个测试只是为了检查你是否也可以在 plpython3u 可以使用时加载模块。在这种情况下,您需要安装必须与 Python 3.7 兼容的 Python 软件包。似乎必须使用 pip 而不是 conda,因为 Python 本来是要从官方网站下载的。为避免依赖冲突,最好使用 Poetry 作为包管理器(类似于 conda,仅适用于 pip)。

当执行 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? 的 PostgreSQL 查询时,这绝对不是我对标准 setter 的期望,例如 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;

旁注结束


任何使用 LANGUAGE plpython3u 的测试查询都会导致错误:

ERROR: server closed the connection unexpectedly

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

当我 运行 在此之后的另一个查询时,它 运行s,但在单击“继续”之前,我得到:

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?

这可能会被线程 PosgreSQL 11 lost connection when i'm trying to create function with plpython3u [WIN10, pgAdmin4 3.5] 解决。这样的答案表明 v3.7.9 或 v3.7.10 或其他子版本确实很重要! 我是否需要从源安装 3.7.10 版本才能获得最新版本版本?

我不想从源代码安装 Python 3.7.10 只是为了检查一下。谁说从 v3.6.5 更改为 v3.6.7 确实解决了上面 link 中的问题,而不是因为新安装而发生的事情?

我也可以试用 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

但由于 v3.6.7 版本曾经似乎有效,我看不出我应该投资于此的理由。

学分转到:

相关:

Windows 使用 EDB 和 Stack Builder 安装

EDB and Stack Builder 是 PostgreSQL 网站推荐的安装方式。我在 Cannot install plpython for postgres 12 找到了这个(一个线程处理根本无法创建扩展,因此无能为力)。 我安装了 PostgreSQL 10,因为 plpython3u 在 timescaleDB Linux 容器中与它一起工作(参见下面的“Docker”),我希望这个较低的 PostgreSQL 版本会解决它。但是使用这种官方安装方法,使用 EDB,然后使用 Stack Builder 额外的“pl/python 语言包”,我仍然得到同样的错误。

问题

Python 3.7 的哪个子版本(v3.7.10、v3.7.0 或其他;也许我的 v3.7.9 也已经正确,因为 plpython 扩展可以用它创建) 肯定与 PostgreSQL13 一起工作,如果不只是通过测试,如何才能发现这一点?如果选择正确的 Python 子版本不是这里的问题(更有可能),我还能如何修复使用LANGUAGE plpython3u:

ERROR: server closed the connection unexpectedly

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

(这是 psql: server closed the connection unexepectedly 的一个问题,但并不关注这个 Python 扩展问题)

The application has lost the database connection.

(这是 PosgreSQL 11 lost connection when i'm trying to create function with plpython3u [WIN10, pgAdmin4 3.5] 的一个问题,但意味着从源代码安装 v3.7.10 只是为了拥有最新的子版本,我试图找出正确的子版本版本或其他获取它的技巧 运行 这样做之前)

解决方法:plpython3u 确实适用于 Linux!所以在 Linux.

上使用它

最后一段不是问题的一部分,只是列出了 Linux 上的一些步骤,作为在此期间 Windows plpython3u 安装不起作用时的替代方法。

Docker:

  • 在 Windows 上,安装 Docker Desktop(推荐)或在 WSL2 上使用 Docker。否则,只需在 Linux.

    上直接安装 Docker
  • 可以在 Docker PostgreSQL 9.6 - installing extension plpython3u (clashing with quantile extension).

    找到一个典型的 postgres Docker 设置,您可以轻松将其更改为更新的版本
  • Docker 有一个问题,您需要额外的技巧,以便即使您删除容器也能保存数据库,例如:

    • pg_dump / pb_restore / psql ... > / psql... < 备份到本地 Linux 磁盘,然后从您选择的已安装卷恢复数据库,或者
    • 用于永久保存数据库的 Web 服务器。
  • 您可能还会从像 , to start with, or take the official postgres image using docker-compose 指南这样的线程中瞥见作为 postgres 基础的线程,并通过 plpython3 对其进行扩展。

  • 一个无法使用 plpython3u 的容器中的一个主要技巧是添加 SymLinks 而不是硬编码安装路径,请参阅 . 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: 。如果无法安装所需的包,plpython3u 在这个 docker 容器中没有任何价值。这就是为什么你应该使用更新的 Docker PostgreSQL 映像(或者例如 timescaleDB),这样你就不会 运行 陷入 Python 3.6 依赖项的遗留问题。

独立

当永久和本地保存数据变得更加重要时,您也可以尝试独立安装 Linux。

  • Linux 安装的官方指南位于 PostgreSQL Downloads and PostgreSQL Wiki Apt
  • 此 link 展示了如何安装扩展:PostgreSQL: how to install plpythonu extension, using for example postgresql-plpython3-13 for postgres 13; in 9/2021, this installs Python 3.8.10. I can confirm that it works! I could create the plpython3u return_version() function of above and run it. If you need to import packages that need to be installed, see for example

猜出的答案(全错;请查看已接受的答案)

凭借 WSL、WSL2 和 Docker Desktop,多年来,Linux 已成为 Windows 的朋友。 Windows 似乎鼓励这一点。在 Linux 上转向 postgreSQL 可能是最近 Windows 对 plpython3u 的支持不佳的原因。同时,您应该将其安装在 Linux 上(独立或在 Docker 容器中)。

但是 Windows 安装可能出了什么问题?

  • 如前所述,Windows 没有像 Linux 那样得到 PostgreSQL 的关注。我想在 Windows 上,我必须从源代码安装 PostgreSQL,连同 plpython 扩展及其依赖项,才能将 plpython3u 正确地安装到 运行。

  • 也许,正常的 Windows 安装程序也不支持 plpython,只是因为一个技术细节:上面问题中的查询显示:PL/Python3U untrusted procedural language。通常的生产系统可能不允许使用它。例如,Web 服务器服务 TimescaleForge(timescaleDB,基于 PostgreSQL)已经回答说,由于存在安全风险,他们不提供任何 plpython 扩展,即使客户要求也是如此。他们宁愿为明确的问题提供可信的扩展,而不是可以做任何事情的完整语言,因此存在安全风险。显然,您可以在从源代码构建时使用不受信任的扩展,就像 TimescaleForge 使用他们自己的扩展一样。

  • 可能需要设置 PATH 变量,如 “Module not found” when importing a Python package within a plpython3u procedure 的答案中所述。

  • 也许在 Windows 上,Python 的默认版本必须在安装前更改某处?这只是 a Linux installation using make, with Python settings in /etc/make.conf

    的一个非常模糊的猜测
  • 最后:

plpython3u 似乎有可能 运行 在 Windows 上的 PostgreSQL 中使用与上述 link 的 Docker 文件中相同的安装技巧] 以上,,其中 plpython3u 工作:

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

因此,必须安装 .plpython3-depspostgresql-plpython3 并且必须添加符号链接。

也许,这样的 SymLinks 也已经是 Windows 上的主要技巧了,尽管我无法在快速测试中使用 SymLinks,请参阅 PostgreSQL on Windows: get “plpython3u” extension to run with the help of SymLinks? 自从解决方案要容易得多,请参阅其他答案。

Windows 和 Postgres 13

的解决方法

我终于可以在 Python 3.7.0 上使用它了。 如果有人正在寻找解决方案,他们可以安装 Python 3.7.0。当然,后续版本中引入的任何新功能都将不可用。我不得不重构我的代码以删除 f-strings。为了方便在存储过程和函数中使用 Python,这是一个小小的折衷。

PostgresSQL 版本:13.4-2

Python版本下载linkhttps://www.python.org/ftp/python/3.7.0/python-3.7.0-amd64.exe

虽然我在另一个 post 上有这个答案,但我发现在这里给出完整的答案而不是仅仅链接是有价值的,再加上一些编辑在这里和那里稍微扩展一下。


我也在尝试同样的事情。虽然我不是专家而且我的错误也有点不同,但这里有一些事情需要检查:

第一步

  • share\extension\下应该有plpython3u.controlplpython3u--1.0.sql才能做到CREATE EXTENSION plpython3u;
  • 确保您在上面的命令中没有任何拼写错误。

第 2 步

  • lib\下面应该有一个plpython3.dll。这个可能是经过上述步骤创建的。
  • 确保 lib\ 在您的 PATH 中。

第三步

  • 没有PYTHONHOME,服务器崩溃。
  • PYTHONHOME 应该在 system/user 环境中设置,或者应该在服务器启动之前设置。似乎版本不如设置此名称重要。 plpython3.dll 似乎在寻找 python39.dll 但我可以在 3.8 安装中使用它。
  • python 版本差异应该仅在您尝试对该版本使用特定功能时引发错误。如果需要,请安装另一个 new/old 版本。只是不要忘记 PYTHONHOME.

我使用的是 Postgres 的压缩版本,所以下面是我 运行 服务器的方式。

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:我不允许 python 安装程序在环境中设置东西,因为我使用许多版本并且没有版本管理器。所以它通常会导致我出现这些类型的错误,但它们在这里和那里进行了很好的心理锻炼:)