psycopg2 ImportError: undefined symbol: PQconninfo psycopg2导入错误:未定义的符号:PQconninfo

9

无法导入psycopg2

在python控制台输出:

import psycopg2

Traceback (most recent call last): File "", line 1, in File "/home/user/.py_virtualenvs/verb_py3/lib/python3.5/site-packages/psycopg2/init.py", line 50, in

from psycopg2._psycopg import ( # noqa ImportError: /home/user/.py_virtualenvs/verb_py3/lib/python3.5/site-packages/psycopg2/_psycopg.cpython-35m-x86_64-linux-gnu.so: 未定义符号: PQconninfo

*提示:可能是由于PQconninfo符号未定义导致的问题。*

嗨,你得到答案了吗? - Siddaram H
如果你从源代码构建,有人有解决方案吗? - Kemin Zhou
4个回答

19
安装psycopg2-binary包解决了我的问题。 pip install psycopg2-binary

7

这可能是底层系统中的缺陷问题。可能会有多个版本的共享库,在运行时您可能无法找到正确的库。通常很难解决。由于我也遇到了同样的问题,我将尝试找出问题的原因。这将比提供固定的解决方案更有用。我仍需要为自己找到解决方案:

1. 从更新的版本构建libpq库。
2. 找到编译psycopg2时使用的适当的libpq。

进入psycopg2的源目录:

myuid@mycomputer:~/Downloads/psycopg2$ find . -name "*.c" | xargs grep PQconninfo
./psycopg/psycopgmodule.c:    PQconninfoOption *options = NULL;
./psycopg/psycopgmodule.c:    options = PQconninfoParse(Bytes_AS_STRING(dsn), &err);
./psycopg/psycopgmodule.c:            PyErr_SetString(OperationalError, "PQconninfoParse() failed");
./psycopg/psycopgmodule.c:    PQconninfoFree(options);    /* safe on null */
./psycopg/connection_int.c:    PQconninfoOption *connopts, *ptr;
./psycopg/connection_int.c:    connopts = PQconninfoParse(pgdsn, NULL);
./psycopg/connection_int.c:    PQconninfoFree(connopts);
./psycopg/connection_int.c:    PQconninfoOption *options = NULL;
./psycopg/connection_int.c:    if (!(options = PQconninfoParse(dsn, NULL))) {
./psycopg/connection_int.c:    PQconninfoFree(options);
./psycopg/conninfo_type.c:".. seealso:: libpq docs for `PQconninfo()`__ for details.\n"
./psycopg/conninfo_type.c:    PQconninfoOption *options = NULL;
./psycopg/conninfo_type.c:    if (!(options = PQconninfo(self->conn->pgconn))) {
./psycopg/conninfo_type.c:    PQconninfoFree(options);
./psycopg/conninfo_type.c:    PyErr_SetString(NotSupportedError, "PQconninfo not available in libpq < 9.3");
./psycopg/connection_type.c:    PQconninfoOption *options = NULL;
./psycopg/connection_type.c:    if (!(options = PQconninfo(self->pgconn))) {
./psycopg/connection_type.c:    PQconninfoFree(options);
./psycopg/connection_type.c:    PyErr_SetString(NotSupportedError, "PQconninfo not available in libpq < 9.3");
./psycopg/utils.c:/* Make a dict out of PQconninfoOption array */
./psycopg/utils.c:psyco_dict_from_conninfo_options(PQconninfoOption *options, int include_password)
./psycopg/utils.c:    PQconninfoOption *o;

注意:psycopg的作者已经通过该行给出了答案。
"PQconninfo not available in libpq < 9.3"

这意味着问题出在运行时较旧的 libpq 上,否则你可能使用了更新版本的 libpq,否则 psycopg2 可能无法编译。

通过行代码:PQconninfo(self->conn->pgconn),你可以知道 PQconninfo 是一个 C 函数,应该在你的 libpq 库中存在。

错误信息通常会告诉你问题所在,例如我的情况是:

/usr/local/lib/python3.8/site-packages/psycopg2-2.8.5.dev0-py3.8-linux-x86_64.egg/psycopg2
Full error: >>> import psycopg2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/site-packages/psycopg2-2.8.5.dev0-py3.8-linux-x86_64.egg/psycopg2/__init__.py", line 50, in <module>
    from psycopg2._psycopg import (                     # noqa
ImportError: /usr/local/lib/python3.8/site-packages/psycopg2-2.8.5.dev0-py3.8-linux-x86_64.egg/psycopg2/_psycopg.cpython-38-x86_64-linux-gnu.so: undefined symbol: PQconninfo

在这里,您应该找到一个共享库:

_psycopg.cpython-38-x86_64-linux-gnu.so

请看这个库:

ldd _psycopg.cpython-38-x86_64-linux-gnu.so
    linux-vdso.so.1 =>  (0x00007ffe985c7000)
    libpq.so.5 => /usr/lib64/libpq.so.5 (0x00007ff922a13000)
    libpthread.so.0 => /usr/lib64/libpthread.so.0 (0x00007ff9227f7000)
    libc.so.6 => /usr/lib64/libc.so.6 (0x00007ff922429000)
    libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007ff9221b7000)
    libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007ff921d54000)
    libkrb5.so.3 => /usr/lib64/libkrb5.so.3 (0x00007ff921a6b000)
    libcom_err.so.2 => /usr/lib64/libcom_err.so.2 (0x00007ff921867000)
    libgssapi_krb5.so.2 => /usr/lib64/libgssapi_krb5.so.2 (0x00007ff92161a000)
    libldap_r-2.4.so.2 => /usr/lib64/libldap_r-2.4.so.2 (0x00007ff9213bb000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ff922e87000)
    libk5crypto.so.3 => /usr/lib64/libk5crypto.so.3 (0x00007ff921188000)
    libdl.so.2 => /usr/lib64/libdl.so.2 (0x00007ff920f84000)
    libz.so.1 => /usr/lib64/libz.so.1 (0x00007ff920d6e000)
    libkrb5support.so.0 => /usr/lib64/libkrb5support.so.0 (0x00007ff920b5e000)
    libkeyutils.so.1 => /usr/lib64/libkeyutils.so.1 (0x00007ff92095a000)
    libresolv.so.2 => /usr/lib64/libresolv.so.2 (0x00007ff920741000)
    liblber-2.4.so.2 => /usr/lib64/liblber-2.4.so.2 (0x00007ff920532000)
    libsasl2.so.3 => /usr/lib64/libsasl2.so.3 (0x00007ff920315000)
    libssl3.so => /usr/lib64/libssl3.so (0x00007ff9200bc000)
    libsmime3.so => /usr/lib64/libsmime3.so (0x00007ff91fe94000)
    libnss3.so => /usr/lib64/libnss3.so (0x00007ff91fb65000)
    libnssutil3.so => /usr/lib64/libnssutil3.so (0x00007ff91f935000)
    libplds4.so => /usr/lib64/libplds4.so (0x00007ff91f731000)
    libplc4.so => /usr/lib64/libplc4.so (0x00007ff91f52c000)
    libnspr4.so => /usr/lib64/libnspr4.so (0x00007ff91f2ee000)
    libselinux.so.1 => /usr/lib64/libselinux.so.1 (0x00007ff91f0c7000)
    libcrypt.so.1 => /usr/lib64/libcrypt.so.1 (0x00007ff91ee90000)
    librt.so.1 => /usr/lib64/librt.so.1 (0x00007ff91ec88000)
    libpcre.so.1 => /usr/lib64/libpcre.so.1 (0x00007ff91ea26000)
    libfreebl3.so => /usr/lib64/libfreebl3.so (0x00007ff91e823000)

注意这一行:libpq.so.5 => /usr/lib64/libpq.so.5
现在只关注这个库中的PPconninfo(它有很多函数和数据)
nm -D /usr/lib64/libpq.so.5 | grep PQconninfo
000000000000cb90 T PQconninfoFree
000000000000df30 T PQconninfoParse

看起来你没有PQconninfo函数。

我认为通过说明如何解决这个问题会更有帮助,这可能会有助于你解决许多类似的问题。

现在我将在我的系统上添加解决方案:

结果发现我的系统上有多个libpg。

cd /usr
find . -name "libpq*"
... many others ignored
./pgsql-11/lib/libpq.so

然后将LD_LIBRARY_PATH更新为/usr/pgsql-11/lib:/usr/local/lib64,问题就解决了。

python3.8
Python 3.8.1 (default, Jan  7 2020, 15:07:37) 
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2

1
谢谢Kemin!你的调试流程帮了我很多。显然,我有两个库postgresql-libs.x86_64和postgresql12-libs.x86_64。对我来说,解决方案是yum remove postgresql-libs.x86_64。 - Mahmut ARIKAN

2
使用conda重新安装psycopg2而不是使用pip解决了该问题。

对我也是一样,谢谢 @tomanizer。如果其他人需要,这里是链接 https://anaconda.org/anaconda/psycopg2 (记得从conda环境内安装)。 - Giampaolo Ferradini

0

就像@Kemin Zhou在其中一个答案中所说的那样,这个问题的原因之一可能是旧的libpq.so文件

我目前正在使用Cent OS 7,并安装了postgresql-lib的版本为:

$ yum list installed | grep postgres
Failed to set locale, defaulting to C
postgresql.x86_64                    9.2.24-4.el7_8                   installed
postgresql-devel.x86_64              9.2.24-4.el7_8                   installed
postgresql-libs.x86_64               9.2.24-4.el7_8                   installed

我甚至无法更新它,因为yum找不到更高版本的软件包:

$ yum list --showduplicates postgresql
Failed to set locale, defaulting to C
Loaded plugins: fastestmirror, langpacks
Loading mirror speeds from cached hostfile
 * epel: mirrors.ircam.fr
Installed Packages
postgresql.x86_64 9.2.24-4.el7_8 installed
Available Packages
postgresql.i686                    9.2.24-2.el7                    base
postgresql.x86_64                  9.2.24-2.el7                    base
postgresql.i686                    9.2.24-2.el7_7                    updates
postgresql.x86_64                  9.2.24-2.el7_7                    updates
postgresql.i686                    9.2.24-4.el7_8                    updates
postgresql.x86_64                  9.2.24-4.el7_8                    updates

这个链接帮了我很大的忙。

使用这个链接,我首先添加了包含更新的postgresql10-libs的存储库:

$ yum install https://download.postgresql.org/pub/repos/yum/10/redhat/rhel-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

然后我安装了更新的postgresql10-libs

$ yum install postgresql10-libs.x86_64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接