[英]Why does my Python script fail when I run it from SQL Server Agent?
I have a python script that works fine when I run it in an IDE.我有一个 python 脚本,当我在 IDE 中运行它时工作正常。 If I execute it from a command line, I have to be in the directory in which is resides in order for it to run properly.如果我从命令行执行它,我必须在它所在的目录中才能正常运行。 If I try to run it as an agent job or with an Execute Process Task in SSIS it fails.如果我尝试将其作为代理作业运行或使用 SSIS 中的执行流程任务运行,则会失败。
The script inside the agent job looks like this:代理作业中的脚本如下所示:
py E:\Opt\AppDirectory\foo.py
SET EXITCODE = %ERRORLEVEL%
IF %EXITCODE% EQ 0 (
REM Script Ran Sucessfully
EXIT 0
)
IF %EXITCODE% EQ 1 (
REM Script Error
EXIT 1
)
When I run this, or in SSIS, I get:当我运行这个,或者在 SSIS 中,我得到:
Traceback (most recent call last):
File "E:\Opt\AppDirectory\foo.py", line 76, in <module>
encoder = jl.load('model.joblib')
File "C:\ProgramData\Anaconda3\lib\site-packages\joblib\numpy_pickle.py", line
590, in load
with open(filename, 'rb') as f:
FileNotFoundError: [Errno 2] No such file or directory: 'model.joblib'
model.joblib lives in the exact same directory as foo.py. model.joblib 与 foo.py 位于完全相同的目录中。 It's really weird when it says it can't find the file, but I'm staring right at it.当它说找不到文件时真的很奇怪,但我正盯着它看。
The job can find foo.py.该作业可以找到 foo.py。 Why can't it seem to find model.joblib?为什么似乎找不到 model.joblib?
When calling from SQL SERVER like you have you need to have sys.exit(0) as the last thing to do.从 SQL SERVER 调用时,您需要将 sys.exit(0) 作为最后一件事。 I've ran into this so many times where the script executes fine but fails from SQL server agent.我遇到过很多次脚本执行良好但从 SQL 服务器代理失败的情况。
My work around has always been to wrap XYZ in a function.我的工作一直是将 XYZ 包装在 function 中。 In the below you will get a divide by zero to show sql server will give you the error message.在下面,您将得到除以零,以显示 sql 服务器会给您错误消息。 If you remove that error on purpose you will see SQL server succeed.如果您故意删除该错误,您将看到 SQL 服务器成功。
import sys
def test():
try:
x = 1/0
if 1 > 0:
return
except BaseException as e:
print(e)
sys.exit(1)
test()
sys.exit(0)
Go ahead and check it out it should work with your: Go 提前检查一下它应该适用于您的:
py E:\Opt\AppDirectory\foo.py
SET EXITCODE = %ERRORLEVEL%
IF %EXITCODE% EQ 0 (
REM Script Ran Sucessfully
EXIT 0
)
IF %EXITCODE% EQ 1 (
REM Script Error
EXIT 1
)
This is not THE answer but I'm going to post what I did for now.这不是答案,但我将发布我现在所做的。 This was for a client on a deadline so I just slapped something together.这是在截止日期前为客户准备的,所以我只是一起拍了一些东西。 I'll post a much more in depth analysis in a few weeks.我将在几周后发布更深入的分析。
The first thing was I needed to have an absolute path to model.joblib.第一件事是我需要有一个到 model.joblib 的绝对路径。 That's my bad.那是我的错。 I normally work in Jupyter Lab and forgot that was necessary.我通常在 Jupyter Lab 工作,却忘记了这是必要的。
However, that didn't fully fix the problem.然而,这并没有完全解决问题。 The job ran but it was like it was skipping over executing the script which was weird.作业运行了,但它就像跳过执行奇怪的脚本一样。 The final solution was to use an Execute Process Task in SSIS to run the script, then change the agent job from CmdExec to SSIS package and that made everything work right.最终的解决方案是使用 SSIS 中的 Execute Process Task 来运行脚本,然后将代理作业从 CmdExec 更改为 SSIS package 并且一切正常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.