What is the right way to use PostgreSQL with PyQt5

Viewed 1616

I use PostgreSQL 9.6.17 (installed on Linux server on LAN) and have Win10 (or Win7) clients with installed Python 3.7 or 3.8 and PyQt 5.13.2, and my PyQt5 app that uses that PostgreSQL server works ok, but I really don't know what I'm doing.

I'll describe the problem. If I don't have PostgreSQL installed on Win client (I don't need it because I use PostgreSQL on Linux server) or have installed it but not in the path, my app crashes with the error:

"QSqlDatabase: QPSQL driver not loaded".

So, I need some drivers. And I install PostgreSQL 9.6.x on Win client and have it in the path and after that everything works ok, but only if I had luck and picked the right PostgreSQL version.

The alternative is that I don't install PostgreSQL 9.6.x (why would I need to install it) on a client machine and just copy some dll files at the app directory. If I find the right files (drivers), everything works ok, but if I don't, the app crashes with the error:

"QSqlDatabase: QPSQL driver not loaded"

or worse, recognize the PostgreSQL database on the server, works ok sometimes, but after the first, second or third query it crashes.

Driver combination I copy to my app directory that works with PyQt 5.13.2:

Timestamp                      Size File
25/02/2016  07:19         1,015,973 libiconv-2.dll
07/01/2016  09:02         1,550,023 libintl-8.dll
10/07/2019  20:20           145,408 libpq.dll

If I install PyQt 5.14 or 5.15 (instead of PyQt 5.13.2), the app crashes, and I am afraid to upgrade PyQt5 to versions 5.14 and more.

So, my question is: How do I know which drivers (dll files) I should copy to my app directory with various versions of PyQt5, that's the mystery to me. For example, what drivers should I use with PyQt versions 5.14 or 5.15 because those 3 dlls from above don't work anymore? Finding the right drivers is completely random guess job and I really don't know what I'm doing and I can say I had luck with drivers for PyQt 5.13.2. And also, I don't know if copying the drivers to my app directory (or having them in some folder that is in the path) is the right way at all?

There's a fine answer here:

QT5: Failed to load psql driver in windows

"It's quite likely to be failing because there's a dependency of qsqlpsql.dll missing - either libpq.dll, or one of the libraries that libpq build requires." ... "You should use the same libpq your Qt's qsqlpgsql.dll was compiled against if possible."

If that's true, how should I know with what libpq library qsqlpgsql.dll was compiled in? I suppose PyQt 5.13.2's qsqlpgsql.dll is compiled with a different version than PyQt 5.14.x's qsqlpgsql.dll or even 5.15.x's qsqlpgsql.dll.

Also, this link has some clues: QPSQL driver not loaded Qt

And generally, what's the best way to work with PostgreSQL in PyQt5. It obviously doesn't work out of the box if (the right version of) PostgreSQL is not installed on a client machine or appropriate drivers are not in path.

UPDATE:
I will put the question through hypothetical example. Let's suppose I have an app in Qt (PyQt), version Qt x.y.z (for example 5.15.0) on user client Win10 computers and Postgres a.b.c (for example 9.6.17) installed on Linux server that is reached from client computers through LAN (or VPN, or whatever). I'm not supposed to install Postgres on client Win10 computers. What files (Postgres dll or lib drivers) depending on Qt x.y.z and Postgres a.b.c do I have to have in user's app directory or path in order my app works correctly, and how to find that files. So, I need a formula: (*.dll, *.dll,,,) = f(x.y.z, a.b.c).

UPDATE (2020-09-25):
My problem is solved all by itself. With the combination Py 3.8.3, PyQt 5.15.1 it now works ok. I tested it on several Win client computers.

2 Answers

So in your update sections You have 2 systems:

System 1) Server with Linux OS e.g.

  • maybe ( Qt version 5.15.0 )
  • PostgreSql 9.6.17
  • maybe ( Python 3.1.1 )

System 2) Client with Win OS

  • Qt version 5.1.0
  • PostgreSql 9.6.17
  • Python 3.1.1

I would suggest your client system should have at least minimum you server library (here 9.6.17) versions. Or check library compatibility for each library separate.

suggestion A: why not building PyQt from source with libversion of your choise for system 2 and maybe for system 1 (if needed) and you will have your *.dll and *.so files for both systems. Please read the article how to configure qt with specific driver support: how to add db driver xy to qt

suggestion B Pack your python app via python installer pyinstaller inlcuding your dll files.

general win-os workflow of shipping your app

A) to use all dll files (for qt and PostgreSQL) from your build environment and copy them in the same folder like the executable. Maybe you use the program Dependency Walker
to figure out, which of these are linked. (most of the times found in qt installation directory)

B) Ship your app with all dll files, and make sure the destination os has the same architecture ( i86| amd64| etc) and also the same PostgreSQL server version is used.

I realize that your target is just to establish a connection with your PostgreSQL server and interact with your DB.

So you can write bare python service to interact with a PostgreSQL server. With the use of psycopg2-binary, I think, you can easily achieve what you want.

If you implement it this way, there is no need in PostgreSQL drivers on your client machine.

Related