Запись набора записей ADODB в сводный кэш с Python - PullRequest
1 голос
/ 05 марта 2020

Я работаю над проектом, в котором я конвертирую некоторый код VBA в Python, чтобы Python взаимодействовал с Excel почти так же, как VBA. В этом конкретном случае я использую библиотеку win32com, чтобы Python извлекал данные из базы данных Oracle через соединение ADODB и записывал полученный набор записей непосредственно в сводный кэш. Т.е. создание сводной таблицы с данными из внешнего источника.

import win32com.client

Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants

# Create and Open Connection
conn = win32com.client.Dispatch(r'ADODB.Connection')
DSN = 'Provider=OraOLEDB.Oracle; Data Source=localhost:1521/XEPDB1; User Id=system; Password=password;'
conn.Open(DSN)

# Create Excel File
wb = Excel.Workbooks.Add()
Sheet1 = wb.Worksheets("Sheet1")

# Create Recordset
RS = win32com.client.Dispatch(r'ADODB.Recordset')
RS.Open('SELECT * FROM employees', conn, 1, 3)

# Create Pivot Cache
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlExternal, Version=win32c.xlPivotTableVersion15)

# Write Recordset to Pivot Cache
PivotCache.Recordset = RS # <~~ This is where it breaks!

# Create Pivot Table
Pivot = PivotCache.CreatePivotTable(TableDestination:=Sheet1.Cells(2, 2), TableName:='Python Test Pivot', DefaultVersion:=win32c.xlPivotTableVersion15)

# Close Connection
RS.Close()
conn.Close()

# View Excel
Excel.Visible = 1

Я успешно извлекаю данные через ADODB и создаю файл Excel, но когда я пытаюсь записать полученный набор записей в сводный кеш с помощью установив PivotCache.Recordset = RS, я получаю следующую ошибку.

[Running] venv\Scripts\python.exe "c:\Project\Test\debug_file_test.py"
Traceback (most recent call last):
  File "c:\Project\Test\debug_file_test.py", line 29, in <module>
    PivotCache.Recordset = RS # <~~ This is where it breaks!
  File "c:\Project\venv\lib\site-packages\win32com\client\__init__.py", line 482, in __setattr__
    self._oleobj_.Invoke(*(args + (value,) + defArgs))
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, 'No such interface supported\r\n', None, 0, -2146827284), None)

[Done] exited with code=1 in 0.674 seconds

Кто-нибудь может пролить свет на то, что я делаю неправильно?

1 Ответ

1 голос
/ 14 марта 2020

Я закончил тем, что нашел решение проблемы, и хочу опубликовать ответ для любого, кто может столкнуться с этим вопросом в какой-то момент.

Вместо создания набора записей с помощью Recordset.Open() Я попытался использовать Команда объекта и создать набор записей с помощью cmd.Execute(). Оказывается, что Execute возвращает кортеж, мне пришлось передать cmd.Execute()[0] в набор записей, чтобы заставить его работать.

Это не отвечает, почему мой исходный код не работает, но он дает ответ для , как записать набор записей ADODB в PivotCache с Python.

import win32com.client

#Initiate Excel Application
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application')
win32c = win32com.client.constants

# Create and Open Connection
conn = win32com.client.Dispatch('ADODB.Connection')
cmd = win32com.client.Dispatch('ADODB.Command')
DSN = 'Provider=OraOLEDB.Oracle; Data Source=localhost:1521/XEPDB1; User Id=system; Password=password;'
conn.Open(DSN)

# Define Command Properties
cmd.ActiveConnection = conn
cmd.ActiveConnection.CursorLocation = win32c.adUseClient
cmd.CommandType = win32c.adCmdText
cmd.CommandText = 'SELECT * FROM employees'

# Create Excel File
wb = Excel.Workbooks.Add()
Sheet1 = wb.Worksheets("Sheet1")

# Create Recordset
RS = win32com.client.Dispatch('ADODB.Recordset')
RS = cmd.Execute()[0]

# Create Pivot Cache
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlExternal, Version=win32c.xlPivotTableVersion15)
PivotCache.Recordset = RS

# Create Pivot Table
Pivot = PivotCache.CreatePivotTable(TableDestination:=Sheet1.Cells(2, 2), TableName:='Python Test Pivot', DefaultVersion:=win32c.xlPivotTableVersion15)

# Close Connection
RS.Close()
conn.Close()

# View Excel
Excel.Visible = 1

Обновление

Как подсказал @Parfait, приведенный выше код также работает, если RS = cmd.Execute()[0] заменен на

RS.Open(cmd)

, который я на самом деле предпочитаю, потому что это обеспечивает выравнивание между синтаксисом VB и синтаксисом Python.

...