QPSQL驱动未加载——在Windows上用Qt和Python使用Postgres

562 阅读3分钟

如果你试图在PyQt5/6或PySide2/PySide6中使用Postgres,你可能遇到了一个加载驱动的问题。 Qt(正确地)列出了驱动在Qt中是可用的,但当试图加载它时,加载将失败。这是因为Qt库依赖于Postgres自己的库,而这个库在加载路径中必须是可用的。

下面的脚本可以让你测试Postgres库的加载是否正确:

  • PyQt5
  • PyQt6
  • PySide2
  • PySide6
from PyQt5.QtSql import QSqlDatabase
from PyQt5.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")

from PyQt6.QtSql import QSqlDatabase
from PyQt6.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")

from PySide2.QtSql import QSqlDatabase
from PySide2.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")

from PySide6.QtSql import QSqlDatabase
from PySide6.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")

在一个新的命令提示符下执行上述脚本将得到如下输出(如果Postgres无法访问)。

命令

>python test.py
QSqlDatabase: QPSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QODBC QODBC3 QPSQL QPSQL7
Available drivers ['QSQLITE', 'QODBC', 'QODBC3', 'QPSQL', 'QPSQL7']
Unable to connect.
Last error Driver not loaded Driver not loaded

可用的驱动 "列表显示了在你的PyQt5(或PyQt6,或PySide2,或PySide6)安装中可用的Qt驱动。例如,在我的安装中,驱动文件在下面。site-packages\PyQt5\Qt5\plugins\sqldrivers

命令

C:\Users\Martin\AppData\Local\Programs\Python\Python37\Lib\site-packages\PyQt5\Qt5\plugins\sqldrivers> dir

 Volume in drive C has no label.
 Volume Serial Number is 0A6A-65ED

 Directory of C:\Users\Martin\AppData\Local\Programs\Python\Python37\Lib\site-packages\PyQt5\Qt5\plugins\sqldrivers

02/12/2021  14:35    <DIR>          .
02/12/2021  14:35    <DIR>          ..
02/12/2021  14:35         1,412,080 qsqlite.dll
02/12/2021  14:35            98,288 qsqlodbc.dll
02/12/2021  14:35            79,856 qsqlpsql.dll
               3 File(s)      1,590,224 bytes
               2 Dir(s)  174,429,970,432 bytes free

由于Qt Postgres驱动找不到Postgres库,所以出现了Driver not loaded的错误。Qt Postgres驱动是对这些库的一个封装,而不是对Postgres本身的一个完整实现。

为了使其正常工作,你需要确保所需的Postgres库文件在你的路径中可用。你可以通过将你的Postgres安装bin 文件夹添加到你的路径中来做到这一点。例如,在我的电脑上,Postgres被安装在C:\Program Files\PostgreSQL\14\ (我使用的是14版)。我们需要把Postgres的bin 文件夹添加到PATH ,因为这里包含了Qt需要的libpq.dll (Postgres Access Library)。

命令

SET PATH=%PATH%;C:\Program Files\PostgreSQL\14\bin

有了这些,再次运行脚本会显示该驱动已经成功加载。连接仍然没有工作,因为它需要设置用户名和密码。但如果你走到一步,你就知道驱动已经正常工作了。

命令

U:\home\martin\www\pythonguis\content\faq\qt-postgres-driver>python test.py
Available drivers ['QSQLITE', 'QODBC', 'QODBC3', 'QPSQL', 'QPSQL7']
Unable to connect.
Last error connection to server at "localhost" (::1), port 5432 failed: fe_sendauth: no password supplied
QPSQL: Unable to connect

我们可以修改测试脚本,加入你的用户名和密码来完成连接:

  • PyQt5
  • PyQt6
  • PySide2
  • PySide6
from PyQt5.QtSql import QSqlDatabase
from PyQt5.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
db.setUserName("postgres")  # postgres is the default root username
db.setPassword("")    # add your password here
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")
from PyQt6.QtSql import QSqlDatabase
from PyQt6.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
db.setUserName("postgres")  # postgres is the default root username
db.setPassword("")    # add your password here
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")
from PySide2.QtSql import QSqlDatabase
from PySide2.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
db.setUserName("postgres")  # postgres is the default root username
db.setPassword("")    # add your password here
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")
from PySide6.QtSql import QSqlDatabase
from PySide6.QtWidgets import QApplication

app = QApplication([])

db = QSqlDatabase("QPSQL")
db.setUserName("postgres")  # postgres is the default root username
db.setPassword("")    # add your password here
print("Available drivers", db.drivers())

if not db.open():
    print("Unable to connect.")
    print('Last error', db.lastError().text())
else:
    print("Connection to the database successful")

...然后连接将如期完成。

命令

>python test-userpass.py
Available drivers ['QSQLITE', 'QODBC', 'QODBC3', 'QPSQL', 'QPSQL7']
Connection to the database successful