Попытка удалить несколько сообщений электронной почты в папке за пределами папки «Входящие» с помощью Python и Exchangelib

Я пытаюсь удалить все сообщения электронной почты в папке за пределами моей учетной записи. Входящие с помощью Python 3 и exchangelib.

testFolder = account.root / 'Top of Information Store' / 'Test'    
emails = testFolder.all().order_by('-datetime_received')
for email in emails:
    email.delete()
    # FWIW
    #print(email.subject)
    #email.move(to_another_folder)
    #both work fine.

Вышеприведенное печатает только все электронные письма и их свойства.

Я также пробовал:

items=[]
testFolder = account.root / 'Top of Information Store' / 'Test'    
emails = testFolder.all().order_by('-datetime_received')
for email in emails:
    items.append(Message(folder=testFolder))
items.save()
items.delete()

Вышеприведенное зависает и выдает ошибку памяти:

File "C:\Python36-32\lib\site-packages\exchangelib\services.py", line 89, in _
get_elements
    response = self._get_response_xml(payload=payload)
  File "C:\Python36-32\lib\site-packages\exchangelib\services.py", line 171, in
_get_response_xml
    res = self._get_soap_payload(response=r, **parse_opts)
  File "C:\Python36-32\lib\site-packages\exchangelib\services.py", line 260, in
_get_soap_payload
    root = to_xml(response.iter_content())
  File "C:\Python36-32\lib\site-packages\exchangelib\util.py", line 365, in to_x
ml
    return parse(stream, parser=forgiving_parser)
  File "C:\Python36-32\lib\site-packages\defusedxml\lxml.py", line 134, in parse
  elementtree = _etree.parse(source, parser, base_url=base_url)
  File "src\lxml\etree.pyx", line 3424, in lxml.etree.parse
  File "src\lxml\parser.pxi", line 1857, in lxml.etree._parseDocument
  File "C:\Python36-32\lib\site-packages\exchangelib\util.py", line 340, in getv
alue
    res = b''.join(self._bytes_generator)
MemoryError

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


person StrangerDanger    schedule 25.01.2019    source источник


Ответы (2)


Нет необходимости собирать предметы в первую очередь. Как вы уже выяснили, это будет потреблять много памяти. Вместо этого вы можете вызвать .delete() непосредственно в QuerySet. Это будет извлекать только идентификаторы элементов и удалять их партиями.

Существует также метод .empty(), результатом которого является вызов службы EmptyFolder. Это удалит все элементы в папке, даже не извлекая идентификаторы:

testFolder.all().delete()
# Or even faster:
testFolder.empty()
person Erik Cederstrand    schedule 29.01.2019
comment
Потрясающий! .empty() работает отлично! Я ненавижу задавать вопрос по ответу, но есть ли способ сделать .move() в QuerySet? - person StrangerDanger; 30.01.2019
comment
В наборе запросов нет .move(), но вы можете передать набор запросов в account.bulk_move(). - person Erik Cederstrand; 30.01.2019
comment
Я пробовал идти по этому пути... но я делаю это неправильно. qs = testFolder.all(), затем account.bulk_move(qs=, to_folder=newTestFolder) и несколько других вариантов без успеха, все еще получая ошибку памяти. Наверное, это должен быть новый вопрос... - person StrangerDanger; 30.01.2019
comment
Вам не нужно полное содержимое элемента, только идентификаторы:. Это должно уменьшить нагрузку на память: `account.bulk_move(qs= testFolder.all().only('id', 'changekey'), to_folder=newTestFolder) - person Erik Cederstrand; 30.01.2019
comment
Вы супер полезны! Спасибо за вашу помощь и за разработку этого замечательного пакета! Это сэкономит моей команде 200 рабочих часов в месяц! - person StrangerDanger; 31.01.2019
comment
Спасибо. Я рад, что вы нашли меня и мое программное обеспечение полезным! - person Erik Cederstrand; 02.02.2019

Может вместо удаления попробовать переместить в корзину? или мягкое удаление?

person Yongkang Zhao    schedule 25.01.2019