local-research: разобран формат экспорта Apple за 5.5 лет

- девять экспортов, версии 11→13→14; ни один тип записи не исчез, только
  добавлялись — разбор можно писать аддитивно
- Correlation (давление) появился только в 2026 и ломает парсер по одним Record;
  имя файла локализовано, DTD расходится с данными
- коды HealthKit переименовываются: те же записи сна приезжают как Asleep из
  экспорта 2021 и как AsleepUnspecified из свежего
This commit is contained in:
av
2026-08-01 14:20:54 +03:00
parent 7ed82af450
commit 7ee55057e0
4 changed files with 169 additions and 10 deletions
+29 -7
View File
@@ -9,14 +9,36 @@
Это же основание для устаревания нижнего слоя и единственный способ поднять
историю глубже недели: дыра старше недели проходами синхронизации не чинится.
Формат разобран на девяти экспортах за 5.5 лет (находки 42–45), гадать не
придётся:
- **версии 11 → 13 → 14**, на 14 стоит больше года; за всё время **ни один тип
записи не исчез**, только добавлялись. Значит незнакомый тип — новый тип, а
не сломанный парсер: падать на нём нельзя;
- **`Correlation`** — обёртка из двух записей, ею приезжает давление. Появилась
только в 2026 году. Парсер по одним `<Record>` разберёт давление как две
несвязанные метрики и потеряет их парность;
- **`WorkoutStatistics`** внутри тренировки — с 2024 года;
- **имя файла локализовано**: `экспорт.xml`, не `export.xml` — так во всех
девяти архивах;
- **DTD расходится с данными** (в v11 у `<Me>` на атрибут больше объявленного)
— валидировать документ его же DTD нельзя;
- объём: 1.6 ГБ XML и 3.6 млн записей в свежем экспорте — только потоковый
разбор, документ целиком в память не влезет.
Шаги:
- разбор `экспорт.xml` (HealthKit Export Version 14, `<Record>` с
`startDate`/`endDate`/`value`/`sourceName`/`device`) в слой `sample`;
- маршруты GPX и ЭКГ отдельными CSV — они не в XML;
- заливка кусками по годам: файл измеряется сотнями мегабайт.
- потоковый разбор `экспорт.xml` в слой `sample`, включая `Correlation`;
- `HeartRateVariabilityMetadataList` с `InstantaneousBeatsPerMinute` — это
тот же `heartbeatSeries`, что в HAE (находка 39), 1.25 млн ударов;
- маршруты GPX и ЭКГ отдельными файлами — их в XML нет;
- заливка кусками по годам, идемпотентно: повторный импорт того же архива не
должен ничего менять;
- `export_cda.xml` игнорируем — это клинический формат тех же данных.
Готово, когда история за несколько лет лежит в слое `sample`, а суммы по нему
сходятся с часовым слоем HAE на пересечении периодов.
Готово, когда история за несколько лет лежит в слое `sample`, повторный импорт
не меняет ничего, а суммы по слою сходятся с часовым слоем HAE на пересечении
периодов.
Есть готовый файл для проверки: `/home/av/MediaEverything/HealthData/apple_health/`.
Архивы: `/home/av/MediaEverything/HealthData/apple_health/` — девять штук,
2021-12 … 2026-08. Старые версии формата годятся как регрессионный набор.