# バッチ設計書 44-import_records

## 概要

本ドキュメントは、JSONファイルからデータベースレコードをインポートするinvokeタスク「import_records」の設計書です。

### 本バッチの処理概要

**業務上の目的・背景**：環境間のデータ移行、バックアップからの復元、またはテストデータのセットアップのために、JSONファイルに保存されたレコードをInvenTreeデータベースにインポートする必要があります。このバッチは、Djangoのloaddataコマンドをラップし、認証データと一般データを適切な順序でインポートします。

**バッチの実行タイミング**：データの復元、環境構築、またはテストデータのセットアップが必要な場合に手動で実行します。

**主要な処理内容**：
1. 入力ファイルの存在確認
2. オプションで既存データの削除（clear=Trueの場合）
3. JSONファイルの読み込みと前処理
4. 認証データ（auth.*）と一般データの分離
5. 権限情報の空配列への置換
6. 認証データを先にインポート
7. 一般データをインポート
8. 一時ファイルの削除（retain_temp=Falseの場合）
9. 後処理としてrebuild_modelsとrebuild_thumbnailsを実行

**前後の処理との関連**：export_recordsタスクと対になるデータインポート機能です。export_recordsでエクスポートしたJSONファイルをインポートできます。後処理としてrebuild_modelsとrebuild_thumbnailsが自動実行されます。

**影響範囲**：データベースの全テーブルに影響する可能性があります。clear=Trueの場合は既存データが削除されます。

## バッチ種別

データインポート / データ復元

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意（メンテナンス時間帯を推奨） |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| 入力ファイル | インポートするJSONファイルが存在すること |
| データベース接続 | データベースへの接続が確立されていること |
| Python環境 | 正しいPython仮想環境がアクティブであること |
| ファイル形式 | JSONファイルがexport_recordsまたはdumpdataで生成された形式であること |

### 実行可否判定

入力ファイルが存在しない場合はエラーメッセージを出力して終了します。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| filename | str | No | 'data.json' | 入力ファイル名 |
| clear | bool | No | False | インポート前に既存データを削除する |
| retain_temp | bool | No | False | 処理終了後に一時ファイルを保持する |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| JSONファイル | JSON | インポートするデータベースレコード |

### 入力ファイル形式

Djangoのdumpdataコマンド（またはexport_records）で生成されたJSON配列形式：

```json
[
  {
    "model": "app_name.model_name",
    "pk": 1,
    "fields": {
      "field_name": "value"
    }
  }
]
```

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| データベース | DB | インポートされたレコード |
| 一時ファイル | JSON | 認証データファイル、処理済みデータファイル（retain_temp=Trueの場合のみ保持） |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| 認証データファイル名 | {filename}.auth.json |
| 処理済みデータファイル名 | {filename}.data.json |
| 文字コード | UTF-8 |

## 処理フロー

### 処理シーケンス

```
1. パス解決
   └─ 相対パスの場合は絶対パスに変換

2. ファイル存在確認
   └─ ファイルが存在しない場合はエラー終了

3. 既存データ削除（clear=Trueの場合）
   └─ delete_data関数でflushコマンドを実行

4. JSONファイル読み込み
   └─ ファイルを読み込み、JSONをパース

5. データ分離と前処理
   ├─ auth.*モデルを認証データとして分離
   ├─ その他のモデルを一般データとして分離
   └─ auth.group, auth.userの権限を空配列に置換

6. 一時ファイル出力
   ├─ 認証データを{filename}.auth.jsonに出力
   └─ 一般データを{filename}.data.jsonに出力

7. 認証データインポート
   └─ loaddata {filename}.auth.json を実行

8. 一般データインポート
   └─ loaddata {filename}.data.json を実行（除外対象を指定）

9. クリーンアップ
   └─ retain_temp=Falseの場合、一時ファイルを削除

10. 後処理（自動実行）
    ├─ rebuild_models
    └─ rebuild_thumbnails
```

### フローチャート

```mermaid
flowchart TD
    A[import_records開始] --> B[パス解決]
    B --> C{ファイル存在?}
    C -->|No| D[エラー終了]
    C -->|Yes| E{clear=True?}
    E -->|Yes| F[既存データ削除]
    E -->|No| G[JSONファイル読み込み]
    F --> G
    G --> H{JSON有効?}
    H -->|No| I[JSONエラー終了]
    H -->|Yes| J[データ分離]
    J --> K[権限情報を空配列に置換]
    K --> L[一時ファイル出力]
    L --> M[認証データインポート]
    M --> N[一般データインポート]
    N --> O{retain_temp?}
    O -->|No| P[一時ファイル削除]
    O -->|Yes| Q[rebuild_models]
    P --> Q
    Q --> R[rebuild_thumbnails]
    R --> S[import_records完了]
```

## データベース操作仕様

### 操作別データベース影響一覧

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| delete_data | 全テーブル | DELETE | clear=Trueの場合、全データ削除 |
| loaddata (auth) | auth_user, auth_group | INSERT/UPDATE | 認証データのインポート |
| loaddata (data) | 全テーブル（除外対象以外） | INSERT/UPDATE | 一般データのインポート |
| rebuild_models | MPTTモデル | UPDATE | ツリー構造の再構築 |

### テーブル別操作詳細

#### auth_user / auth_group

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | permissions | 空配列 | 権限情報は空に置換 |
| INSERT/UPDATE | user_permissions | 空配列 | ユーザー権限も空に置換 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | FileNotFoundError | 入力ファイルが存在しない | ファイルパスを確認 |
| - | JSONDecodeError | JSONの形式が不正 | JSONファイルの内容を確認 |
| - | OperationalError | データベース接続失敗 | データベースサーバーの起動確認 |
| - | IntegrityError | データ整合性エラー | データの依存関係を確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（自動リトライなし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

1. JSONパースエラー：JSONファイルの形式を確認
2. 認証データインポート失敗：auth関連の依存関係を確認
3. 一般データインポート失敗：外部キーの参照先データが存在するか確認
4. 途中で失敗した場合：delete_data後に再実行を推奨

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | loaddataコマンド単位 |
| コミットタイミング | 各loaddataコマンド完了時 |
| ロールバック条件 | loaddataコマンド内でエラー発生時 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | インポートデータのレコード総数に依存 |
| 目標処理時間 | データ量に依存（通常数秒〜数分） |
| メモリ使用量上限 | データサイズに依存 |

## 排他制御

- 同時実行は禁止
- 複数インスタンス環境では、1つのインスタンスのみでimport_recordsを実行すること
- インポート中は他のユーザーアクセスを制限することを推奨

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 開始ログ | バッチ開始時 | "Importing database records from '{filename}'" |
| 進捗ログ | 認証データインポート時 | "Importing user auth data..." |
| 進捗ログ | 一般データインポート時 | "Importing database records..." |
| 進捗ログ | クリーンアップ時 | "Removing temporary files" |
| 終了ログ | バッチ終了時 | "Data import completed" |
| エラーログ | エラー発生時 | エラー詳細 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 実行時間 | 環境依存 | システム管理者 |
| エラー発生 | 1件以上 | システム管理者 |

## 備考

- `post=[rebuild_models, rebuild_thumbnails]`により、インポート完了後にツリー構造の再構築とサムネイル再生成が自動実行される
- 認証データ（auth.*）を先にインポートする理由は、users.ownerモデルがContentType外部キーを持つため
- auth.groupとauth.userのpermissionsフィールドは常に空配列に置換される
- content_excludes関数で定義された除外対象（django_q, exchange等）はインポート時も除外される
- JSONファイルの形式が不正な場合はJSONDecodeError例外が発生し、処理が中断される
- clear=Trueを指定するとflushコマンドが実行され、全データが削除されるため注意が必要
