0

I have been stuck with this for a while but if I get this right - nothing like it. I am trying to run a python script from SQL Server using xp_cmdshell using the below code

EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
GO

EXEC xp_cmdshell '<PythonInstallationFolderPath>\python.exe "<.py FilePath>"'

EXEC sp_configure 'xp_cmdshell', 0
RECONFIGURE
GO

The above code works fine - it runs the python script (I can say that it runs because the python script saves some data from me in an excel sheet). In the python script, I have a code to do some formatting on the excel sheet:

import xlwings as xw
# create an excel instance app object as a context manager to make sure files are closed safely
app = xw.App(visible = True)
# open workbook
excel_book = app.books.open(fr'<ExcelFilePath>\Dummy_Name.xlsx')
# fetch active sheet 
ws = excel_book.sheets.active
# select Cell A1 and press Ctrl + A
tbl_range = ws.range("A1").expand('table')
# create table 
ws.api.ListObjects.Add(1, ws.api.Range(tbl_range.address))
# save and close workbook and app object
excel_book.save()
excel_book.close()
app.quit()

This code runs perfect when I run it from a Python IDE (like anaconda prompt or VSCode). However, when I call the python script from SQL Server using the command xp_cmdshell as shown above, it fails with the below error:

Traceback (most recent call last):
  File "", line 80, in <module>
    app = xw.App(visible = False)
  File "C:\Anaconda\lib\site-packages\xlwings\main.py", line 212, in __init__
    self.impl = xlplatform.App(spec=spec, add_book=add_book)
  File "C:\Anaconda\lib\site-packages\xlwings\_xlwindows.py", line 296, in __init__
    self._xl = COMRetryObjectWrapper(DispatchEx('Excel.Application'))
  File "C:\Anaconda\lib\site-packages\win32com\client\__init__.py", line 113, in DispatchEx
    dispatch = pythoncom.CoCreateInstanceEx(clsid, None, clsctx, serverInfo, (pythoncom.IID_IDispatch,))[0]
pywintypes.com_error: (-2147024891, 'Access is denied.', None, None)

I can with certainty say that the above error is associated with the xlwings section above. Thats because if I remove the xlwings section, the remaining code in my python script runs correctly. From the traceback, I can understand that access is denied. Hence, I tried a few ideas like using xw.App(visible = False) instead of xw.App(visible = True) and trying to also run using context manager. But these dint work.
I am new to xlwings and also to shell commands. I found that this error has relation to pywin32 library from other stackoverflow question and answers like these: Win32com codes not working on IIS ImportError: No module named win32com.client

I presume xlwings library or xp_cmdshell does some sort of call to pywin32 library to perform the operations above. I also found that this library is an advanced library for conversing with Windows which suggests to me that it will be difficult for me to debug. Hence, I am seeking your expert help. I have been stuck with this for sometime now and would really appreciate a direction to explore towards or maybe help me pinpoint what I am doing wrong.

  • Why use `xp_cmdshell` when SQL Server natively supports running Python? – Thom A Jul 05 '22 at 17:49
  • I used machine learning services and found it to be a bit slow to run and also the error messages thrown were not so easy to debug. I found calling python scripts from sql agent job was a good way to run python scripts - yet we have been recently moving away from sql agent jobs because we started to have several jobs running together. Hence, finding an easy alternative to sql agent jobs. – LifetimeLearner4706 Jul 05 '22 at 22:38

1 Answers1

0

the traceback you mentioned above shows that it anaconda is being used to execute script. try using local python instead :

Traceback (most recent call last): File "", line 80, in app = xw.App(visible = False) File "C:\Anaconda\lib\site-packages\xlwings\main.py", line 212, in init self.impl = xlplatform.App(spec=spec, add_book=add_book) File "C:\Anaconda\lib\site-packages\xlwings_xlwindows.py", line 296, in init self.xl = COMRetryObjectWrapper(DispatchEx('Excel.Application')) File "C:\Anaconda\lib\site-packages\win32com\client_init.py", line 113, in DispatchEx dispatch = pythoncom.CoCreateInstanceEx(clsid, None, clsctx, serverInfo, (pythoncom.IID_IDispatch,))[0] pywintypes.com_error: (-2147024891, 'Access is denied.', None, None)

Atlas Bravoos
  • 360
  • 2
  • 12
  • win32api.FormatMessage(-2147024891) above returns the string 'Access is denied.\r\n'. and hence I am getting the error --> 'str' object has no attribute 'decode' <--. I am not sure what you are looking for. – LifetimeLearner4706 Jul 06 '22 at 08:42
  • the purpose was to get a comprehensive error. – Atlas Bravoos Jul 06 '22 at 08:44
  • also i noticed that you're using anaconda environment to run snippet. Try using python installed on your system which you most probably used in VsCode, Anaconda environment is notorious for access issues – Atlas Bravoos Jul 06 '22 at 08:46
  • I used both for your code above. Getting same error because e_msg is a string object. – LifetimeLearner4706 Jul 06 '22 at 08:55
  • NO no. ignore debugging script. try running YOUR script with local Python installed – Atlas Bravoos Jul 06 '22 at 08:57
  • I ran it with local python installed and it runs correctly. The error occurs only when I make a call to the script from SQL Server using xp_cmdshell. (EXEC xp_cmdshell 'PythonFolderPath\python.exe "FilePath"') – LifetimeLearner4706 Jul 06 '22 at 09:00