Как использовать win32com для обработки переполнения при запросе Desktop Search? - PullRequest
0 голосов
/ 09 июня 2018

Я запрашиваю базу данных Windows Desktop Search JET (ESE), используя Python + ADO.Это работает, но после ~ 7600 записей я получаю исключение при переходе к следующей записи, используя MoveNext.Я знаю, что это не в EOF, потому что я могу выполнить тот же запрос в VBScript и получить гораздо больше записей с тем же запросом.

Исключение traceback

Traceback (most recent call last):
  File "test_desktop_search.py", line 60, in <module>
    record_set.MoveNext()
  File "<COMObject ADODB.Recordset>", line 2, in MoveNext
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147215865), None)

Запрос этой ошибки показывает, что это:

  • Константа: adErrDataOverflow
  • Значение: 3721 -2146824567 0x800A0E89
  • Описание: Значение данных слишком велико для представления типом данных поля.

Это прекрасно работает в VBScript (но, возможно, только из-за плохой обработки ошибок).В PowerShell есть следующая ошибка (после того, как она намного дальше, чем Python, примерно в том же месте, что и VBScript):

Exception from HRESULT: 0x80041607
At C:\Users\doday\PycharmProjects\desktop_search_test\Get-DesktopSearchData.ps1:43 char:5
+     $recordSet.MoveNext();
+     ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException

Я не смог найти этот код ошибки в документации Microsoft, но он, вероятно, связан.Как видите, поле Facility равно 4 (ошибка HRESULT для интерфейса) и код 1607.

MCVE

#!/usr/bin/env python
"""
Test querying Desktop Search from Python
"""

import csv
import pywintypes
from win32com.client import Dispatch

# connection
conn = Dispatch("ADODB.Connection")
connstr = "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
conn.Open(connstr)

# record set
record_set = Dispatch("ADODB.Recordset")
q = "SELECT System.ItemName, System.ItemTypeText, System.Size, System.IsDeleted, System.DateAccessed, System.Kind, System.ItemDate, System.Search.Store, System.ItemParticipants, System.ItemAuthors, System.IsRead, System.Message.AttachmentNames FROM SystemIndex"
# record_set.ActiveConnection = conn
record_set.Open(q, conn)

# header
# I'm only selecting a few fields for this test, see
# https://msdn.microsoft.com/en-us/library/windows/desktop/bb419046(v=vs.85).aspx
header = [
    "System.ItemName",
    "System.ItemTypeText",
    "System.Size",
    "System.IsDeleted",
    "System.DateAccessed",
    "System.Kind",
    "System.ItemDate",
    "System.Search.Store",
    "System.ItemParticipants",
    "System.ItemAuthors",
    "System.IsRead",
    "System.Message.AttachmentNames"
]

# output to file
with open("ds_output.tsv", "w", newline='') as out_f:
    w = csv.DictWriter(out_f, fieldnames=header, delimiter='\t')
    w.writeheader()
    record_set.MoveFirst()
    while not record_set.EOF:
        record = dict.fromkeys(header)

        # populate fields
        for h in header:
            record[h] = record_set.Fields.Item(h).Value

        # write record
        w.writerow(record)

        try:
            record_set.MoveNext()
        except pywintypes.com_error as e:
            # can't figure out how to resolve this or at least advance to next record despite this error
            print("Error: {}".format(e.args))

# clean up
record_set.Close()
record_set = None
conn.Close()
conn = None

Что я пробовалдо сих пор

  • Я пытался удалить столбец / поле "System.Message.AttachmentNames" из моего запроса, но это фактически заставило его работать быстрее / после меньшего количества записей с той же ошибкой (первое число в исключенииargs - то же самое).
  • Я пытался использовать только одно поле ("System.ItemName"), что делало его вдвое больше, чем другие попытки в Python, но заканчивалось с ошибкой UnicodeEncodeError (которая не отображаетсябыть связано с другой ошибкой, показанной выше, которая не позволяет ему когда-либо указывать имя файла с этой ошибкой).
  • Я пытался использовать PowerShell и также получил COMException (вывод ошибки показан выше).

1 Ответ

0 голосов
/ 09 июня 2018

Ваш трекбек показывает код ошибки -2147352567.Это DISP_E_EXCEPTION, очень общее исключение COM.Он содержит ошибку -2147215865, которая также равна 0x80041607, что также является QUERY_E_TIMEDOUT.

Я использую этот бесплатный инструмент веб-сайта - я сделал это - чтобы найти ошибки и другие константы, подобные этому: https://www.magnumdb.com/search?q=-2147215865

Таким образом, на самом деле все они сообщают об одной и той же ошибке времени ожидания.

Вы можете увеличить время ожидания ADO, как описано здесь: Возникли проблемы с SystemIndex (я люблю его, но не могу заставить его работать так, как я)Хотите)

или вы можете полностью удалить его с помощью кода, подобного следующему:

conn.CommandTimeout = 0
...