我有一个使用 sqlalchemy 来管理 sqlite 数据库的应用程序。该应用程序是使用 pyqt5 创建的,我已经为数据库创建了所有类。现在我正在使用 pyinstaller 创建 .exe 文件。在 dist 文件夹中,我有 .exe 文件,当我运行它时,会出现此错误:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) unable to open database file(Background on this error at: https://sqlalche.me/e/20/e3q8)
我一直在网上寻找解决方案,我发现这个错误是因为 uri 中存在额外的正斜杠,但这不是我的情况(必须是三个,如下所示)。这是我在应用程序中上传数据库的代码(当我使用 python 运行它时一切正常,但使用 .exe 文件则不行)
ROOT = os.path.dirname(__file__)
ICONS_WIDTH = 40
ICONS_HEIGHT = 40
BG_WIDTH = 1920
BG_HEIGHT = 1080
try:
from ctypes import windll
myappid = "isDev.sistemaGestorUrimare.administrativo.version1.0"
windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
except ImportError:
pass
class MainWindow(QtWidgets.QMainWindow):
theme_changed = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
self.setWindowTitle("Sistema Gestor Urimare")
self.setWindowIcon(QtGui.QIcon(":/logo/logo.png"))
self.setStatusBar(QtWidgets.QStatusBar(parent=self))
self.settings = QtCore.QSettings("Urimare", "urimareApp")
if not self.settings.contains("theme"):
self.settings.setValue("theme", "/resources/light")
self.engine = create_engine("sqlite:///model/database.db", echo=False)
if not os.path.isfile(ROOT + "/model/database.db"):
Base.metadata.create_all(self.engine)
Base.metadata.bind = self.engine
在这篇post中,用户遇到了同样的问题,有人尝试了解决方案,但我不太明白,如果解决方案有效,他们也不会发布。
这是我的.spec 文件内容:
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['main.py'],
pathex=[],
binaries=[],
datas=[
("resources", "resources"),
("resources.qrc", "."),
(r"model\database.db", "model"),
(r".venv\Lib\site-packages\qtstylish\compiled", "qtstylish\compiled")
],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='urimare',
icon=r".\resources\iconosApp\urimareIcono01.ico",
debug=True,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='urimare',
)
提前致谢!
我相信您的代码的问题是,当您的应用程序编译为 .exe 时,它不会复制 db 文件。修复方法可能是将 db 文件复制到新文件夹,但是如果 sqlite 找不到 db 文件,它会自动创建一个新的 db 文件。
这让我得出另一个结论:您的应用程序没有创建 db 文件的权限。
解决方案1:将db文件复制到编译好的exe的文件夹下
解决方案2:如果您希望应用程序第一次启动时自动创建db文件,并且不想复制db文件,请确保您的应用程序具有写入权限。