PyInstaller打包的exe生成SEPA DEBIT XML时异常终止
PyInstaller打包后生成SEPA XML报错的解决方法
问题场景
我有一个Python项目,包含生成SEPA DEBIT格式XML文件的功能。在PyCharm中运行一切正常,但用PyInstaller打包为exe文件后,生成XML时程序报错终止。xmlschema文件夹存在于项目的/.venv/Lib/site-packages路径下,但PyInstaller未打包对应的schema文件路径。
核心生成代码如下:
def create_sepa_xml(data_ra, filename, data_own_bank): b = "" if data_own_bank[0][9] == 1: b = "True" elif data_own_bank[0][9] == 0: b = "False" client = { "name": data_own_bank[0][0], "IBAN": data_own_bank[0][1], "BIC": data_own_bank[0][2], "batch": b, "creditor_id": data_own_bank[0][11], "currency": "EUR", } sepa = SepaDD(client, schema="pain.008.002.02") typ = ["FRST", "RCUR", "OOFF"] index = int(data_own_bank[0][8]) tage_einzugsfrist = data_own_bank[0][7] for e in data_ra: datu = convert_mandate_date(e[17]) amount = round(e[23], 2) amount2 = int(amount * 100) redat = convert_redat(e[3]) renr = e[2] kunr = e[4] text = "ReNr:" + str(renr) + " KuNr:" + str(kunr) + " ReDat:" + redat debtor = { "name": e[12], "IBAN": e[15], "BIC": e[14], "amount": amount2, "type": typ[index], # FRST, RCUR, OOFF, FNAL "collection_date": date.today() + timedelta(days=int(tage_einzugsfrist)), "mandate_id": e[16], "mandate_date": date(datu.year, datu.month, datu.day), "description": text, } sepa.add_payment(debtor) pain_message = sepa.export() example = parseString(pain_message).toprettyxml() with open(filename, 'w') as file: file.write(example) msgbox.callMessagebox_ok("*.XML Datei erstellt.", "erledigt", )
问题根源
SepaDD依赖xmlschema库生成XML,该库需要读取本地的XSD schema文件。PyInstaller默认不会自动打包第三方库的静态资源文件,导致exe运行时找不到schema文件路径。
解决方法一:打包时用--add-data手动包含schema文件
找到虚拟环境中xmlschema的schema目录,路径为./.venv/Lib/site-packages/xmlschema/schemas,执行打包命令时添加该路径:
pyinstaller --add-data ".venv/Lib/site-packages/xmlschema/schemas;xmlschema/schemas" 你的主脚本文件名.py
Windows系统用分号;分隔源路径和目标路径,Linux/macOS用冒号:。
解决方法二:修改代码指定schema文件的绝对路径
使用pkg_resources获取xmlschema的资源路径,确保运行时能找到schema文件,修改初始化SepaDD的代码:
import pkg_resources # 获取对应schema文件的绝对路径 schema_path = pkg_resources.resource_filename('xmlschema', 'schemas/pain.008.002.02.xsd') # 用路径初始化SepaDD sepa = SepaDD(client, schema=schema_path)
解决方法三:通过.spec文件配置资源
- 生成spec文件:
pyinstaller --name 你的应用名 你的主脚本文件名.py
- 打开生成的
你的应用名.spec文件,在datas列表中添加schema路径:
a = Analysis( # ... 其他配置 datas=[('.venv/Lib/site-packages/xmlschema/schemas', 'xmlschema/schemas')], # ... 其他配置 )
- 用spec文件打包:
pyinstaller 你的应用名.spec
注意事项
- 确保虚拟环境中安装的
xmlschema是最新版本,避免版本兼容问题 - 打包时尽量使用项目对应的虚拟环境,减少依赖冲突
- 如果使用方法二时出现
pkg_resources相关错误,可在spec文件的hiddenimports中添加'pkg_resources'
内容的提问来源于stack exchange,提问作者Albert.O
相关产品推荐
相关产品推荐

