简体   繁体   English

sp_execute_external_script 找不到 setuptools 安装的模块

[英]sp_execute_external_script can't find modules installed by setuptools

I am actively developing a Python module that I would like to deploy in SQL Server 2017 installed locally, so I deploy the module in c:\\Program Files\\Microsoft SQL Server\\<Instance Name>\\PYTHON_SERVICES\\Lib\\site-packages using setuptools like so:我正在积极开发一个 Python 模块,我想在本地安装的 SQL Server 2017 中部署该模块,因此我使用setuptools将该模块部署在c:\\Program Files\\Microsoft SQL Server\\<Instance Name>\\PYTHON_SERVICES\\Lib\\site-packages像这样:

"c:\Program Files\Microsoft SQL Server\<Instance_Name>\PYTHON_SERVICES\python" setup.py develop

This produces an .egg-info directory in my project root, and a .egg-link file in the site-packages directory mentioned above.这会在我的项目根目录中生成一个.egg-info目录,并在上面提到的site-packages目录中生成一个.egg-link文件。 The .egg-link file correctly points to the .egg-info directory in my project root, so it appears setuptools is working correctly. .egg-link文件正确指向了我项目根目录中的.egg-info目录,所以看起来setuptools工作正常。

Here's my setup.py for reference:这是我的setup.py供参考:

from setuptools import setup

setup(
    setup_requires=['pbr'],
    pbr=True,
)

And here's the corresponding setup.cfg file:这是相应的setup.cfg文件:

[metadata]
name = <module_name>
description = <Module Description>
description-file = README.md
description-content-type = text/markdown

[files]
package_root = py/src

Since I am just trying to make the plumbing work, I have a single python script called uploader.py in <project_root>/py/src :由于我只是想让管道工作,我在<project_root>/py/src有一个名为uploader.py Python 脚本:

#uploader.py
class Upload:
    pass

With this deployment in place, I am hoping to simply import the module I just published through .egg-link into a sp_execute_external_script call like so:有了这个部署,我希望简单地import我刚刚通过.egg-link发布的模块importsp_execute_external_script调用中,如下所示:

execute sp_execute_external_script @language= N'Python', @script= N'from <module_name>.uploader import Upload';

However, executing this stored procedure from SSMS produces the following error message:但是,从 SSMS 执行此存储过程会产生以下错误消息:

Msg 39004, Level 16, State 20, Line 10
A 'Python' script error occurred during execution of 'sp_execute_external_script' with HRESULT 0x80004004.
Msg 39019, Level 16, State 2, Line 10
An external script error occurred: 

Error in execution.  Check the output for more information.
Traceback (most recent call last):
  File "<string>", line 5, in <module>
  File "C:\SQL-MSSQLSERVER-ExtensibilityData-PY\MSSQLSERVER01\C08BB9A7-66B5-4B5E-AAFC-B0248EE64199\sqlindb.py", line 27, in transform
    from <module_name>.uploader import Upload
ImportError: No module named '<module_name>'

SqlSatelliteCall error: Error in execution.  Check the output for more information.
STDOUT message(s) from external script: 
SqlSatelliteCall function failed. Please see the console output for more information.
Traceback (most recent call last):
  File "C:\Program Files\Microsoft SQL Server\<Instance_Name>\PYTHON_SERVICES\lib\site-packages\revoscalepy\computecontext\RxInSqlServer.py", line 587, in rx_sql_satellite_call
    rx_native_call("SqlSatelliteCall", params)
  File "C:\Program Files\Microsoft SQL Server\<Instance_Name>\PYTHON_SERVICES\lib\site-packages\revoscalepy\RxSerializable.py", line 358, in rx_native_call
    ret = px_call(functionname, params)
RuntimeError: revoscalepy function failed.

I have obviously redacted module_name and Instance_Name from the error message.我显然已经从错误消息中编辑了module_nameInstance_Name

I tried using install command instead of develop just to make sure the .egg-link file is not a problem.我尝试使用install命令而不是develop来确保.egg-link文件没有问题。 install installs the .egg-info file in site-packages but I get the same error. installsite-packages安装.egg-info文件,但我得到了同样的错误。

I also tried removing pbr from the mix, but got the same error.我也尝试从混合中删除pbr ,但得到了同样的错误。

Lastly, I tried adding my <project_root> to sys.path as suggested by How can I use an external python module with SQL 2017 sp_execute_external_script?最后,我尝试按照How can I use an external python module with SQL 2017 sp_execute_external_script 的建议将我的<project_root>添加到sys.path , but that didn't help either. ,但这也无济于事。

So at this point, I don't have a clue what I might be doing wrong.所以在这一点上,我不知道我可能做错了什么。

The python version is 3.5.2 and I don't think an __init__.py is needed in the project for it to qualify as a module. python 版本是3.5.2 ,我认为项目中不需要__init__.py才能将其作为模块。 Inserting a blank __init__.py in py/src doesn't help either.py/src中插入一个空白的__init__.py也无济于事。

My pip version is 19.3.1 and setuptools version is 44.0.0 and pbr version is 5.4.4 and I have confirmed all modules are installed in the site-packages directory mentioned above.我的pip的版本是19.3.1setuptools版本是44.0.0pbr的版本是5.4.4 ,我已确认所有模块都安装在site-packages目录上面提到的。

Based on my extensive experimentation, it appears that sp_execute_external_script doesn't follow symlinks (ie through the .egg-link file).根据我的大量实验,似乎sp_execute_external_script不遵循符号链接(即通过.egg-link文件)。 Therefore, development mode installations will not work, whether you use setuptools , pip , pbr or anything else.因此,无论您使用setuptoolspippbr还是其他任何方式,开发模式安装都不起作用。

I even tried symlinking <package_name> folder as an OS symlink.我什至尝试将<package_name>文件夹符号链接为操作系统符号链接。 Since I am on Windows, I used mklink /D command on Command Prompt to symlink /py/src/<package_name> inside site-packages .由于我在 Windows 上,我在命令提示符上使用mklink /D命令来符号链接/py/src/<package_name>内的site-packages While the command goes through correctly, and I can see the symlinked folder in File Explorer, sp_execute_external_script fails to detect the package.虽然命令正确执行,并且我可以在文件资源管理器中看到符号链接文件夹,但sp_execute_external_script无法检测到包。 Which tells me that there is probably something in sp_execute_external_script code that avoids traversing symbolic links.这告诉我sp_execute_external_script代码中可能有一些东西可以避免遍历符号链接。

I wonder if there is a way to make it traverse symbolic links.我想知道是否有办法让它遍历符号链接。

The only workable solution is to develop a package's code under its own directory, so, in my case /py/src/<package_name> .唯一可行的解​​决方案是在其自己的目录下开发包的代码,因此,在我的情况下是/py/src/<package_name> Then, before running exec sp_execute_external_script @language=N'python', @script=N'...' copy the <package_name> folder to the site-packages directory.然后,在运行exec sp_execute_external_script @language=N'python', @script=N'...'<package_name>文件夹复制到site-packages目录。

This is, sort of, equivalent to setup.py install , but bypasses the creation of intermediate files and directories.这在setup.py install相当于setup.py install ,但绕过了中间文件和目录的创建。 So I am going to stick with this simple--though odious--approach.所以我将坚持使用这种简单——尽管令人讨厌——的方法。

I am hoping somebody more knowledgeable would offer a better way to solve this problem.我希望知识渊博的人会提供更好的方法来解决这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM