Search code examples
pythonpython-3.xpymongodnspython

PyInstaller issue with Pymongo


I'm attempting to make a windows executable that uses Pymongo and Kivy. I'm using PyInstaller to create it. I am using Python 3.6.

When I run main.py directly it works as expected but when I attempt to run main.exe it will open the kivy window but crash when I try to access the remote MongoDB with the following error

pymongo.errors.ConfigurationError: The "dnspython" module must be installed to use mongodb+srv:// URIs
[11992] Failed to execute script main

My spec file is:

from kivy.deps import sdl2, glew

block_cipher = None


a = Analysis(['c:\\mypath\\main.py'],
         pathex=['c:\\mypath\\build'],
         binaries=[],
         datas=[],
         hiddenimports=['dnspython'],
         hookspath=[],
         runtime_hooks=[],
         excludes=[],
         win_no_prefer_redirects=False,
         win_private_assemblies=False,
         cipher=block_cipher,
         noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
         cipher=block_cipher)
exe = EXE(pyz,
      a.scripts,
      [],
      exclude_binaries=True,
      name='main',
      debug=False,
      bootloader_ignore_signals=False,
      strip=False,
      upx=True,
      console=True )
coll = COLLECT(exe,
      Tree('c:\\mypath'),
      a.binaries,
      a.zipfiles,
      a.datas,
      *[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
      strip=False,
      upx=True,
      name='main')

I first tried it without dnspython listed as a hidden import.

I tried explicitly importing dnspython in main.py but get a module not found error when directly running main.py. ModuleNotFoundError: No module named 'dnspython'

I did run python -m pip install --upgrade dnspython but received 'Requirement already up-to-date: dnspython '

I'm not sure what else to try!


Solution

  • The issue is that the import isn't dnspython (despite that being the name given in the error and used by pip) the actual module is just dns.

    As such I was able to resolve the issue by changing the spec file so that the hiddenimports is:

    hiddenimports=['dns']