2

Been playing around with pyinstaller and cx_freeze the last couple of days trying to get my app to run as a .exe.

In python everything works as intended.

I have the following items in a folder ready for compile...

files for compile

rawCodes.py is my main.

mcnc.py is my PyQt5 GUI.

mcnclogo_rc.py contains all the images i used in my GUI.

The following is a list of my imports in my main...

import sqlite3
from mcnc import Ui_MainWindow
import mcnclogo_rc
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, 
QDialog, QComboBox
import sys
import math

It seems that when i run pyinstaller it completes the process and produces 3 folders as expected.

The exe is clearly inside the dist folder and all appears to have worked.

However i run the exe and it just opens then closes again and nothing comes up.

I am convinced that my mcnc.py file is not being included and therefore i am not seeing a GUI (pyqt5).

Does anyone know how to specifically list mcnc.py in my SPEC file to make sure it is included...same with mcnclogo_rc.

EDIT

I have run the .exe from CMD and i am getting the following traceback...

G:\Yans work in progress\Yans python\Qt\to 
compile\dist\rawCodes>rawCodes.exe
Traceback (most recent call last):
File "rawCodes.py", line 3287, in <module>
File "rawCodes.py", line 22, in __init__
File "rawCodes.py", line 3101, in Load_StainlessDb
sqlite3.OperationalError: no such table: stainless
[13020] Failed to execute script rawCodes

Could it be that my database isnt getting packed properly in to the dist/build?

EDIT 2

I have changed the sqlite3 pathing so it is dynamic however it is still giving exactly the same error...

import sqlite3
import mcnc
from mcnc import Ui_MainWindow
import mcnclogo_rc
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, 
QDialog, QComboBox
import sys
import math
import os

package_dir = os.path.abspath(os.path.dirname(__file__))
db_dir = os.path.join(package_dir, 'codes.db')
print(db_dir)

conn = sqlite3.connect(db_dir)
c = conn.cursor()
c.execute('')

def stainless_list(self):
    stainless_getlist = []

    content = 'SELECT grade FROM stainless ORDER BY prefix ASC'
    res = conn.execute(content)
    for row in res:
        stainless_getlist.append(row[0])

    conn.close

    stainless_getlist.insert(0, "Select...")
    self.comboBox_2.clear()
    self.comboBox_2.addItems(stainless_getlist)

    #print(stainless_getlist)
    return

Then i still get the following error...

G:\Yans work in progress\Yans python\Qt\to 
compile\dist\rawCodes>rawCodes.exe
Traceback (most recent call last):
  File "rawCodes.py", line 3287, in <module>
  File "rawCodes.py", line 22, in __init__
  File "rawCodes.py", line 3101, in Load_StainlessDb
sqlite3.OperationalError: no such table: stainless
[14664] Failed to execute script rawCodes

EDIT 3

Here is the print of my dir paths once compiled...

G:\Yans work in progress\Yans python\Qt\to 
compile\dist\rawCodes>rawCodes.exe
G:\Yans work in progress\Yans python\Qt\to compile\dist\rawCodes
G:\Yans work in progress\Yans python\Qt\to compile\dist\rawCodes\codes.db

Here is my code and imports...

import sqlite3
import mcnc
from mcnc import Ui_MainWindow
import mcnclogo_rc
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, 
QDialog, QComboBox
import sys
import math
import os
import os.path as op

try:
    this_file = __file__
except NameError:
    this_file = sys.argv[0]
this_file = op.abspath(this_file)
if getattr(sys, 'frozen', False):
    application_path = getattr(sys, '_MEIPASS', 
    op.dirname(sys.executable))
else:
    application_path = op.dirname(this_file)

sqlite_conn = os.path.join(application_path, 'codes.db')

print(application_path)
print(sqlite_conn)

conn = sqlite3.connect(sqlite_conn)
c = conn.cursor()
c.execute('')

but once compiled and trying to run from the dist it can no longer see the tables in the db.

EDIT 4

I changed my code to the following...

import sqlite3
import mcnc
from mcnc import Ui_MainWindow
import mcnclogo_rc
from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidgetItem, 
QDialog, QComboBox
import sys
import math
import os
import os.path as op

try:
    this_file = __file__
except NameError:
    this_file = sys.argv[0]
this_file = op.abspath(this_file)
if getattr(sys, 'frozen', False):
    application_path = getattr(sys, '_MEIPASS', op.dirname(sys.executable))
else:
    application_path = op.dirname(this_file)

sqlite_conn = os.path.join(QApplication.applicationDirPath(), 'codes.db')

print(application_path)
print(sqlite_conn)

conn = sqlite3.connect(sqlite_conn)
c = conn.cursor()
c.execute('')

I now get the following traceback...

G:\Yans work in progress\Yans python\Qt\to 
compile\dist\rawCodes>rawCodes.exe
QCoreApplication::applicationDirPath: Please instantiate the QApplication 
object first
G:\Yans work in progress\Yans python\Qt\to compile\dist\rawCodes
codes.db
Traceback (most recent call last):
  File "rawCodes.py", line 3303, in <module>
  File "rawCodes.py", line 38, in __init__
  File "rawCodes.py", line 3117, in Load_StainlessDb
sqlite3.OperationalError: no such table: stainless
[3268] Failed to execute script rawCodes

EDIT 5

app = QApplication(sys.argv)

sqlite_conn = os.path.join(QApplication.applicationDirPath(), 'codes.db')

G:\Yans work in progress\Yans python\Qt
C:/Program Files (x86)/Python37-32\codes.db

Got a straight up error and couldnt connect to the db at all. The db folder now points to C: drive.

Yan
  • 127
  • 1
  • 8
  • 1
    Use the full path of the .db – eyllanesc Apr 18 '19 at 03:22
  • Isnt it the case that if the .db is in the same directory as the python script that it doesnt need a full path? How do i put a full path if the .exe will be installed on different PC's in different locations...surely the path of the .db will change depending? – Yan Apr 18 '19 at 06:55
  • 1
    First do what you are told to rule out if that is the problem, then I will show you how to create the correct relative path – eyllanesc Apr 18 '19 at 06:57
  • Thanks will do as soon as im home from work. – Yan Apr 18 '19 at 11:25
  • I have done as you asked and it works in python, however still have the same error occurring...i could use some help to get a relative path setup. see above EDIT 2. 'stainless' is the 1st table to be referenced in my script ...so it is failing on any connection being made once the dist exe is used. – Yan Apr 18 '19 at 18:54
  • 1
    read https://stackoverflow.com/questions/404744/determining-application-path-in-a-python-exe-generated-by-pyinstaller – eyllanesc Apr 18 '19 at 18:56
  • I have added another edit above showing the code i grabbed from your link...still same issue as before...cannot see tables in the db once compiled. – Yan Apr 18 '19 at 19:35
  • try with: `sqlite_conn = os.path.join(QApplication.applicationDirPath(), 'codes.db')` – eyllanesc Apr 18 '19 at 19:38
  • updated code as suggested and i have posted my traceback in EDIT 4. Thanks for all the help so far, really appreciate it. – Yan Apr 18 '19 at 21:07
  • add `app = QApplication(sys.argv)` before `sqlite_conn = ...` – eyllanesc Apr 18 '19 at 21:12
  • by adding that line i got an error when running the script in python prior to compile. See EDIT 5. – Yan Apr 18 '19 at 21:31
  • I think it is worth adding that the codes.db file is packed in to the .exe after compile. On clicking the .exe the codes.db file pops out in to the same directory as the .exe....not sure if this may be the reason that it cant connect to the tables. – Yan Apr 18 '19 at 23:55

3 Answers3

1

After many hours i noticed that the script was failing at the point where it tried to access the tables of the db and not at the connect statement in my compile.

Upon further inspection i noticed that after the compile has run the codes.db was missing until i clicked the .exe to run. Then a codes.db popped out of the exe with 0kb and no tables.

I have concluded that i need to research how to include the original .db file in the compile and not allow it to create a new empty .db in its absence.

I have tested this by over writing the empty .db with the original .db and suddenly my .exe works perfectly.

Yan
  • 127
  • 1
  • 8
  • I also encourage you to use sqlite via sqlalchemy. I did not have any issue with dbs or having to fix hidden imports. This SO question is an illustration: https://stackoverflow.com/questions/47114772/sqlite-pyqt5-to-standalone-exe-python-3-6-3-pyinstaller – Abdur-Rahmaan Janhangeer Jan 15 '20 at 08:31
1

I believe the answer is simple. Let's analyse the stacktrace

enter image description here

The red part is the error name: OperationalError. From the docs:

Exception raised for errors that are related to the database’s operation and not necessarily under the control of the programmer, e.g. an unexpected disconnect occurs, the data source name is not found, a transaction could not be processed, etc. It is a subclass of DatabaseError.

But, the green part tells us:

no such table: stainless

which simply means the table is not found as it was either deleted or it was not created at all.

And, as far as i can see, no table creation code is to be found. It's not a PyInstaller error.

0

Your exe closes then opens up because you have no body code. In your main code's body add this:

input()

That should fix it.

xilpex
  • 2,929
  • 2
  • 11
  • 41
  • I do not think that your code does not have a body but that the OP considers that the information that is needed to reproduce the problem is only the imports of the modules that it uses. – eyllanesc Apr 17 '19 at 23:14
  • i have nearly 1000 lines of code in rawCodes.py (my main py). It runs perfectly in python. – Yan Apr 17 '19 at 23:53
  • I don't see any reference to mcnc.py in my dist folder at all...is that normal? Is there a way of specifying either in command line or in the spec file to include the other 2 scripts? – Yan Apr 17 '19 at 23:56
  • It was not what i thought it might be. in the modulegraph cross reference i can see that all scripts are present and correcly bundled. I think its just my Sqlite3 database that is now having a problem...i posted a shot of the error above. – Yan Apr 18 '19 at 01:17