无法在 PySide2 上加载 QMYSQL 驱动程序
Unable to load QMYSQL Driver on PySide2
如何使用带有 python3.8 的 Pyside2 (pip) 安装和加载 Qmysql 驱动程序?我已经尝试下载 git:qtbase 并从那里编译驱动程序,但我很幸运。
这个答案不仅包括 Linux 的安装,还包括其他 OS 的安装,此外它还适用于 pyqt5
Qt 使用的二进制文件与 PyQt5/PySide2 使用的二进制文件相同,因为它们使用相同的基本代码,因此您必须编译插件。
在这种情况下,要编译 mysql 插件,您必须遵循 the official manual,总结起来就是:
- 安装依赖项,在本例中为 mysql-connector-c
- 在pyqt5/pyside2上安装与pyqt5/pyside2编译时相同版本的Qt,在windows上安装MSVC等开发工具,在Ubuntu上安装build-essentials,在XCode上安装build-essentials在 Mac 上OS,等等
- 下载源代码,在本例中为 qtbase repository.
- 编译插件。
要找出库编译时使用的 Qt 版本,可以使用以下命令:
- PyQt5
python -c "from PyQt5.QtCore import QT_VERSION_STR; print('Qt version', QT_VERSION_STR)"
- PySide2
python -c "from PySide2.QtCore import qVersion; print('Qt version', qVersion())"
以上根据OS生成libqsqlmysql.so、qsqlmysql.dll或libqsqlmysql.dylib。该文件必须粘贴在路径中:
- PyQt5:
python -c "import os; from PyQt5.QtCore import QLibraryInfo; print('QT_SQL_DRIVER_PATH', os.path.join(QLibraryInfo.location(QLibraryInfo.PrefixPath), 'plugins', 'sqldrivers'))"
- PySide2:
python -c "import os; from PySide2.QtCore import QLibraryInfo; print('QT_SQL_DRIVER_PATH', os.path.join(QLibraryInfo.location(QLibraryInfo.PrefixPath), 'plugins', 'sqldrivers'))"
为了涵盖所有情况,我创建了一个 Github 生成二进制文件的操作:
name: generate_mysql_plugin
on: [push]
jobs:
ci:
name: ${{ matrix.os.name }} Qt-${{ matrix.qt.qt_version }}
runs-on: ${{ matrix.os.runs-on }}
strategy:
fail-fast: false
matrix:
os:
- name: Windows
extension: "dll"
runs-on: windows-2019
- name: Linux
extension: "so"
runs-on: ubuntu-20.04
- name: MacOS
extension: "dylib"
runs-on: macos-10.15
qt:
- name: 5.15
qt_version: 5.15.0
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: ${{ matrix.qt.qt_version }}
dir: ${{ github.workspace }}/qt/
- name: clone qtbase
run: git clone -b ${{ matrix.qt.qt_version }} https://code.qt.io/qt/qtbase.git
- name: Compile mysql plugin on Windows
if: matrix.os.name == 'Windows'
shell: cmd
run: |
choco install wget
wget https://downloads.mysql.com/archives/get/p/19/file/mysql-connector-c-6.1.11-winx64.zip
unzip mysql-connector-c-6.1.11-winx64.zip
copy /y "mysql-connector-c-6.1.11-winx64\lib\libmysql.dll" .
call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cd qtbase/src/plugins/sqldrivers
qmake -- MYSQL_INCDIR="${{ github.workspace }}\mysql-connector-c-6.1.11-winx64\include" MYSQL_LIBDIR="${{ github.workspace }}\mysql-connector-c-6.1.11-winx64\lib"
nmake sub-mysql
nmake install
- name: Compile mysql plugin on Linux
if: matrix.os.name == 'Linux'
run: |
wget https://downloads.mysql.com/archives/get/p/19/file/mysql-connector-c-6.1.11-linux-glibc2.12-x86_64.tar.gz
tar zxvf mysql-connector-c-6.1.11-linux-glibc2.12-x86_64.tar.gz
sudo cp mysql-connector-c-6.1.11-linux-glibc2.12-x86_64/lib/*.so /usr/lib/x86_64-linux-gnu
sudo apt-get install freetds-dev
cd qtbase/src/plugins/sqldrivers
qmake
cd mysql
qmake
make
make install
- name: Compile mysql plugin on MacOS
if: matrix.os.name == 'MacOs'
run: |
brew install wget
wget https://cdn.mysql.com/archives/mysql-connector-c/mysql-connector-c-6.1.11-macos10.12-x86_64.tar.gz
tar zxvf mysql-connector-c-6.1.11-macos10.12-x86_64.tar.gz
sudo cp mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient.dylib mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient_r.dylib
sudo cp mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient.18.dylib mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient_r.18.dylib
sudo cp mysql-connector-c-6.1.11-macos10.12-x86_64/lib/*.dylib /usr/local/lib
cd qtbase/src/plugins/sqldrivers
qmake -- MYSQL_PREFIX="${{ github.workspace }}/mysql-connector-c-6.1.11-macos10.12-x86_64"
make sub-mysql
cd mysql
make install
- name: upload
uses: actions/upload-artifact@v2
with:
path: qtbase/src/plugins/sqldrivers/plugins/sqldrivers/*qsqlmysql.${{ matrix.os.extension }}
name: mysqlplugin-${{ matrix.os.name }}-Qt${{ matrix.qt.name }}
前面的代码生成了你可以找到的插件here。
在Ubuntu的具体情况下可以简化为:
- 将 libqsqlmysql.so 文件复制到 QT_SQL_DRIVER_PATH。
- 执行
sudo apt install libmysqlclient-dev
在Windows的具体情况下可以简化为:
- 将 qsqlmysql.dll 文件复制到 QT_SQL_DRIVER_PATH。
- 下载 mysql-connector-c for windows 并复制脚本旁边的 libmysql.dll。
P.S。几乎一半的信息在 https://doc.qt.io/qt-6/deployment-plugins.html
上正式发布
我在 Windows 10 上使用 PySide6,%QT_SQL_DRIVER_PATH%
对我不起作用。
适用于 PySide6 的是 %QT_PLUGIN_PATH%
环境变量。
假设您已经为 Qt 平台构建(或下载)了一个 SQL 驱动程序到 C:\projects\my-project-1\qt-plugins\sqldrivers
,因此那里有 qsqlmysql.dll
。
CASE #1: 你执行 QSqlDatabase.addDatabase("QMYSQL")
,但你得到以下错误:
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QODBC QPSQL
表示没有找到qsqlmysql.dll
(Qt平台的插件)
修复就是定义环境变量%QT_PLUGIN_PATH%
,把qsqlmysql.dll
放到%QT_PLUGIN_PATH%/sqldrivers/
中。您甚至可以在 Python 脚本 之前 调用 QSqlDatabase.addDatabase
:
os.environ['QT_PLUGIN_PATH'] = r'C:\projects\my-project-1\qt-plugins'
注意,qsqlmysql.dll
必须是使用 MSVC(64 位,因为是 2022 年)构建的发行版本,而不是 MinGW。根据我的经验,调试版本由于某种原因失败。
如果您不想定义 %QT_PLUGIN_PATH%
环境变量,另一种解决方法 是将 qsqlmysql.dll
复制到 个目录:<python-install-dir>/sqldrivers/
或 <python-install-dir>/lib/site-packages/PySide6/plugins/sqldrivers/
.
另一种选择 是这样使用 QCoreApplication.addLibraryPath
:
app = QCoreApplication(sys.argv)
app.addLibraryPath(r'C:\projects\my-project-1\qt-plugins')
还有另一种选择是创建
<python-install-dir>\qt.conf
或 <python-install-dir>\qt6.conf
具有以下内容:
[Paths]
Prefix=C:/projects/my-project-1
Plugins=qt-plugins
还是这样:
[Paths]
Plugins=C:/projects/my-project-1/qt-plugins
N.B。如果 qt.conf
不存在,qt6.conf 将被忽略。如果您使用 qt6.conf
,您 必须 至少创建一个空的 qt.conf
。
CASE #2: 你执行了 QSqlDatabase.addDatabase("QMYSQL")
,但是你得到了以下错误:
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QMARIADB QMYSQL QSQLITE QODBC QPSQL
表示找到了qsqlmysql.dll
,但是它的依赖没有。
qsqlmysql.dll
还需要 3 个 DLL:libmysql.dll
、libcrypto-1_1-x64.dll
、libssl-1_1-x64.dll
。
这些 DLL 必须位于 %PATH%
或当前目录中。
N.B。如果将 DLL 放在 python 脚本附近,如果当前工作目录与脚本的位置不同,这将不起作用。但是您甚至可以在 Python 脚本中修改 %PATH%
。
例如,如果您将所述 DLL 复制到项目的 deps
sub-directory 中:
os.environ["PATH"] += os.pathsep + os.path.join(os.path.dirname(__file__), 'deps')
另一个可能的问题可能是:
- 体系结构不匹配(一些 DLL 是 64 位的,而另一些是 32 位的)。
- 二进制不兼容 - 例如如果“sqldrivers/qsqlmysql.dll”是使用 MinGW 构建的或者它是从 https://github.com/thecodemonkey86/
下载的调试版本
定义环境变量:set QT_DEBUG_PLUGINS=1
- 这可能有助于解决此类问题。
如何使用带有 python3.8 的 Pyside2 (pip) 安装和加载 Qmysql 驱动程序?我已经尝试下载 git:qtbase 并从那里编译驱动程序,但我很幸运。
这个答案不仅包括 Linux 的安装,还包括其他 OS 的安装,此外它还适用于 pyqt5
Qt 使用的二进制文件与 PyQt5/PySide2 使用的二进制文件相同,因为它们使用相同的基本代码,因此您必须编译插件。
在这种情况下,要编译 mysql 插件,您必须遵循 the official manual,总结起来就是:
- 安装依赖项,在本例中为 mysql-connector-c
- 在pyqt5/pyside2上安装与pyqt5/pyside2编译时相同版本的Qt,在windows上安装MSVC等开发工具,在Ubuntu上安装build-essentials,在XCode上安装build-essentials在 Mac 上OS,等等
- 下载源代码,在本例中为 qtbase repository.
- 编译插件。
要找出库编译时使用的 Qt 版本,可以使用以下命令:
- PyQt5
python -c "from PyQt5.QtCore import QT_VERSION_STR; print('Qt version', QT_VERSION_STR)"
- PySide2
python -c "from PySide2.QtCore import qVersion; print('Qt version', qVersion())"
以上根据OS生成libqsqlmysql.so、qsqlmysql.dll或libqsqlmysql.dylib。该文件必须粘贴在路径中:
- PyQt5:
python -c "import os; from PyQt5.QtCore import QLibraryInfo; print('QT_SQL_DRIVER_PATH', os.path.join(QLibraryInfo.location(QLibraryInfo.PrefixPath), 'plugins', 'sqldrivers'))"
- PySide2:
python -c "import os; from PySide2.QtCore import QLibraryInfo; print('QT_SQL_DRIVER_PATH', os.path.join(QLibraryInfo.location(QLibraryInfo.PrefixPath), 'plugins', 'sqldrivers'))"
为了涵盖所有情况,我创建了一个 Github 生成二进制文件的操作:
name: generate_mysql_plugin
on: [push]
jobs:
ci:
name: ${{ matrix.os.name }} Qt-${{ matrix.qt.qt_version }}
runs-on: ${{ matrix.os.runs-on }}
strategy:
fail-fast: false
matrix:
os:
- name: Windows
extension: "dll"
runs-on: windows-2019
- name: Linux
extension: "so"
runs-on: ubuntu-20.04
- name: MacOS
extension: "dylib"
runs-on: macos-10.15
qt:
- name: 5.15
qt_version: 5.15.0
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Install Qt
uses: jurplel/install-qt-action@v2
with:
version: ${{ matrix.qt.qt_version }}
dir: ${{ github.workspace }}/qt/
- name: clone qtbase
run: git clone -b ${{ matrix.qt.qt_version }} https://code.qt.io/qt/qtbase.git
- name: Compile mysql plugin on Windows
if: matrix.os.name == 'Windows'
shell: cmd
run: |
choco install wget
wget https://downloads.mysql.com/archives/get/p/19/file/mysql-connector-c-6.1.11-winx64.zip
unzip mysql-connector-c-6.1.11-winx64.zip
copy /y "mysql-connector-c-6.1.11-winx64\lib\libmysql.dll" .
call "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat"
cd qtbase/src/plugins/sqldrivers
qmake -- MYSQL_INCDIR="${{ github.workspace }}\mysql-connector-c-6.1.11-winx64\include" MYSQL_LIBDIR="${{ github.workspace }}\mysql-connector-c-6.1.11-winx64\lib"
nmake sub-mysql
nmake install
- name: Compile mysql plugin on Linux
if: matrix.os.name == 'Linux'
run: |
wget https://downloads.mysql.com/archives/get/p/19/file/mysql-connector-c-6.1.11-linux-glibc2.12-x86_64.tar.gz
tar zxvf mysql-connector-c-6.1.11-linux-glibc2.12-x86_64.tar.gz
sudo cp mysql-connector-c-6.1.11-linux-glibc2.12-x86_64/lib/*.so /usr/lib/x86_64-linux-gnu
sudo apt-get install freetds-dev
cd qtbase/src/plugins/sqldrivers
qmake
cd mysql
qmake
make
make install
- name: Compile mysql plugin on MacOS
if: matrix.os.name == 'MacOs'
run: |
brew install wget
wget https://cdn.mysql.com/archives/mysql-connector-c/mysql-connector-c-6.1.11-macos10.12-x86_64.tar.gz
tar zxvf mysql-connector-c-6.1.11-macos10.12-x86_64.tar.gz
sudo cp mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient.dylib mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient_r.dylib
sudo cp mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient.18.dylib mysql-connector-c-6.1.11-macos10.12-x86_64/lib/libmysqlclient_r.18.dylib
sudo cp mysql-connector-c-6.1.11-macos10.12-x86_64/lib/*.dylib /usr/local/lib
cd qtbase/src/plugins/sqldrivers
qmake -- MYSQL_PREFIX="${{ github.workspace }}/mysql-connector-c-6.1.11-macos10.12-x86_64"
make sub-mysql
cd mysql
make install
- name: upload
uses: actions/upload-artifact@v2
with:
path: qtbase/src/plugins/sqldrivers/plugins/sqldrivers/*qsqlmysql.${{ matrix.os.extension }}
name: mysqlplugin-${{ matrix.os.name }}-Qt${{ matrix.qt.name }}
前面的代码生成了你可以找到的插件here。
在Ubuntu的具体情况下可以简化为:
- 将 libqsqlmysql.so 文件复制到 QT_SQL_DRIVER_PATH。
- 执行
sudo apt install libmysqlclient-dev
在Windows的具体情况下可以简化为:
- 将 qsqlmysql.dll 文件复制到 QT_SQL_DRIVER_PATH。
- 下载 mysql-connector-c for windows 并复制脚本旁边的 libmysql.dll。
P.S。几乎一半的信息在 https://doc.qt.io/qt-6/deployment-plugins.html
上正式发布我在 Windows 10 上使用 PySide6,%QT_SQL_DRIVER_PATH%
对我不起作用。
适用于 PySide6 的是 %QT_PLUGIN_PATH%
环境变量。
假设您已经为 Qt 平台构建(或下载)了一个 SQL 驱动程序到 C:\projects\my-project-1\qt-plugins\sqldrivers
,因此那里有 qsqlmysql.dll
。
CASE #1: 你执行 QSqlDatabase.addDatabase("QMYSQL")
,但你得到以下错误:
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QODBC QPSQL
表示没有找到qsqlmysql.dll
(Qt平台的插件)
修复就是定义环境变量%QT_PLUGIN_PATH%
,把qsqlmysql.dll
放到%QT_PLUGIN_PATH%/sqldrivers/
中。您甚至可以在 Python 脚本 之前 调用 QSqlDatabase.addDatabase
:
os.environ['QT_PLUGIN_PATH'] = r'C:\projects\my-project-1\qt-plugins'
注意,qsqlmysql.dll
必须是使用 MSVC(64 位,因为是 2022 年)构建的发行版本,而不是 MinGW。根据我的经验,调试版本由于某种原因失败。
如果您不想定义 %QT_PLUGIN_PATH%
环境变量,另一种解决方法 是将 qsqlmysql.dll
复制到 个目录:<python-install-dir>/sqldrivers/
或 <python-install-dir>/lib/site-packages/PySide6/plugins/sqldrivers/
.
另一种选择 是这样使用 QCoreApplication.addLibraryPath
:
app = QCoreApplication(sys.argv)
app.addLibraryPath(r'C:\projects\my-project-1\qt-plugins')
还有另一种选择是创建
<python-install-dir>\qt.conf
或 <python-install-dir>\qt6.conf
具有以下内容:
[Paths]
Prefix=C:/projects/my-project-1
Plugins=qt-plugins
还是这样:
[Paths]
Plugins=C:/projects/my-project-1/qt-plugins
N.B。如果 qt.conf
不存在,qt6.conf 将被忽略。如果您使用 qt6.conf
,您 必须 至少创建一个空的 qt.conf
。
CASE #2: 你执行了 QSqlDatabase.addDatabase("QMYSQL")
,但是你得到了以下错误:
QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QMARIADB QMYSQL QSQLITE QODBC QPSQL
表示找到了qsqlmysql.dll
,但是它的依赖没有。
qsqlmysql.dll
还需要 3 个 DLL:libmysql.dll
、libcrypto-1_1-x64.dll
、libssl-1_1-x64.dll
。
这些 DLL 必须位于 %PATH%
或当前目录中。
N.B。如果将 DLL 放在 python 脚本附近,如果当前工作目录与脚本的位置不同,这将不起作用。但是您甚至可以在 Python 脚本中修改 %PATH%
。
例如,如果您将所述 DLL 复制到项目的 deps
sub-directory 中:
os.environ["PATH"] += os.pathsep + os.path.join(os.path.dirname(__file__), 'deps')
另一个可能的问题可能是:
- 体系结构不匹配(一些 DLL 是 64 位的,而另一些是 32 位的)。
- 二进制不兼容 - 例如如果“sqldrivers/qsqlmysql.dll”是使用 MinGW 构建的或者它是从 https://github.com/thecodemonkey86/ 下载的调试版本
定义环境变量:set QT_DEBUG_PLUGINS=1
- 这可能有助于解决此类问题。