Резервные копии и архивы

Перед любой массовой операцией с файлами делайте резервную копию. Скрипт, который сначала бэкапит, а потом меняет, прощает ошибки — в отличие от того, что сразу переписывает данные.
Суть: бэкап = копия с меткой времени в имени. Архив папки одной строкой делает shutil.make_archive. Метка времени гарантирует уникальность имени.

Автоматизация опасна именно тем, что действует быстро и одинаково. Если в скрипте ошибка, он испортит не один файл, а все сразу. Защита проста: перед изменением сделайте копию. Стоит это копейки дискового места, а спасает часы работы.

Ключевой приём — метка времени в имени бэкапа. Файл report_backup_2026-06-22_14-30-05.zip никогда не конфликтует со вчерашним бэкапом, и по имени сразу видно, когда он сделан. Метку даёт модуль datetime.

Сборку имени бэкапа с меткой времени легко проверить в браузере — это чистый datetime и форматирование строк.

Попробуй сам ▶

from datetime import datetime

def backup_name(base, ext):
    # Метка времени в формате, безопасном для имён файлов
    stamp = datetime(2026, 6, 22, 14, 30, 5).strftime('%Y-%m-%d_%H-%M-%S')
    return f'{base}_backup_{stamp}.{ext}'

print(backup_name('report', 'zip'))
print(backup_name('database', 'sql'))

# Почему двоеточия в метке заменены на дефисы:
bad = datetime(2026, 6, 22, 14, 30).strftime('%H:%M')
print('С двоеточием:', bad, '— такое имя запрещено в Windows!')

Двоеточие в 14:30 кажется безобидным, но в Windows оно запрещено в именах файлов. Поэтому в метке времени для имён всегда используют дефисы. Это типичная грабля кроссплатформенных скриптов.

СТРАТЕГИЯ БЭКАПА

  данные/  --copy-->  данные_backup_<метка>/
     |                        |
  опасная                 хранится
  операция                нетронутым
     |
  результат  (если плохо -> восстановить из бэкапа)

  Сначала копия, потом изменения.

Когда нужно не просто скопировать, а упаковать папку в один файл — на помощь приходит shutil.make_archive. Эта строка трогает диск, поэтому показана как нерабочая в браузере врезка.

import shutil
from datetime import datetime
from pathlib import Path

stamp = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
# make_archive('reports_backup_<stamp>', 'zip', 'reports')
archive = shutil.make_archive(f'reports_backup_{stamp}', 'zip', 'reports')
print('Архив создан:', archive)

# Распаковать обратно:
shutil.unpack_archive(archive, 'restored')

Полезно встроить в стратегию и автоматическую ротацию бэкапов — иначе диск рано или поздно переполнится копиями. Простое правило: храните последние N копий, а более старые удаляйте. Реализуется это легко, ведь метка времени в имени делает копии сортируемыми: отсортировали список бэкапов по имени, оставили N свежих, остальные удалили. Так у вас всегда есть глубина истории для отката, но без бесконтрольного роста. Это превращает бэкап из разового действия в самоподдерживающуюся систему, которая не требует ручного вмешательства и не преподносит сюрприз «диск заполнен» в самый неподходящий момент.

Как работает под капотом

shutil.make_archive(base, format, root) рекурсивно обходит папку root и упаковывает её содержимое в архив. Формат zip доступен везде, gztar (tar.gz) даёт лучшее сжатие на текстах. Функция возвращает путь к созданному архиву — удобно сразу логировать.

Метод strftime превращает объект datetime в строку по шаблону: %Y — год из 4 цифр, %m — месяц, %d — день, %H/%M/%S — часы, минуты, секунды. Обратная операция — strptime — разбирает строку в datetime.

Частые ошибки

  • Запрещённые символы в имени. Двоеточие, слеши и звёздочки в метке времени ломают имя файла на Windows.
  • Перезаписывать единственный бэкап. Без метки времени новый бэкап затирает старый, и откатиться некуда.
  • Хранить бэкап рядом с оригиналом. Если диск умрёт, погибнут оба. Копию лучше уносить в отдельное место.

Best practices

  • Всегда добавляйте метку времени — это история версий бесплатно.
  • Делайте бэкап первым шагом скрипта, до любых изменений.
  • Периодически удаляйте старые бэкапы по дате, чтобы не забить диск.

Итоги. Бэкап с меткой времени — страховка любой автоматизации: копия перед изменениями, уникальное имя через datetime, упаковка через make_archive. Помните про запрещённые символы. С файлами разобрались — переходим к таблицам, самому частому формату данных.

Проверьте себя
1. Почему в метке времени для имени файла используют дефисы вместо двоеточий?
AДефисы короче
BДвоеточие запрещено в именах файлов на Windows
Cdatetime не умеет ставить двоеточия
DТак быстрее сортируется
2. Что возвращает shutil.make_archive?
AРазмер архива в байтах
BСписок упакованных файлов
CПуть к созданному архиву
DОбъект datetime