# 機能設計書 39-データインポート

## 概要

本ドキュメントは、InvenTreeシステムにおけるデータインポート機能の設計を定義する。外部ファイル（CSV、Excel等）からInvenTreeデータベースへのデータ一括取り込みを行う機能を提供する。

### 本機能の処理概要

データインポート機能は、InvenTreeシステムに部品、在庫、サプライヤー情報などを外部ファイルから一括でインポートする。DataImportSessionモデルを通じて、インポートセッションの管理、カラムマッピング、データ検証、バックグラウンド処理を実現する。

**業務上の目的・背景**：新規システム導入時や外部システムからのデータ移行時に、大量のデータを手動で入力するのは非効率。CSVやExcelファイルからデータを一括インポートすることで、データ入力の効率化と入力ミスの削減を実現する。

**機能の利用シーン**：
- 新規システム導入時の既存データ移行
- 外部システムからの部品マスタ取り込み
- サプライヤーからの価格リスト取り込み
- 定期的な在庫データ更新
- 大量データの一括登録

**主要な処理内容**：
1. インポートセッションの作成（ファイルアップロード）
2. カラム抽出とフィールドマッピング
3. マッピングの確認・調整
4. データ検証（行ごとのバリデーション）
5. バックグラウンドでのデータインポート実行
6. インポート結果の確認

**関連システム・外部連携**：
- tablibライブラリ（CSV/Excel読み込み）
- Django-Qバックグラウンドタスク

**権限による制御**：データインポートは認証済みユーザーが可能。インポート先のモデルに対する追加権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 34 | 管理センター画面 | 主画面 | データインポートパネル |

## 機能種別

バッチ処理 / データ移行

## 入力仕様

### インポートセッション作成入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| data_file | file | Yes | インポートファイル | CSV/Excel形式、サポートされた拡張子 |
| model_type | str | Yes | インポート先モデルタイプ | サポートされたモデルであること |
| field_defaults | json | No | フィールドデフォルト値 | JSON形式 |
| field_overrides | json | No | フィールド強制値 | JSON形式 |
| field_filters | json | No | フィールドフィルター | JSON形式 |
| update_records | bool | No | 既存レコード更新モード | true/false |

### カラムマッピング入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| session | int | Yes | セッションID | 有効なセッションID |
| field | str | Yes | フィールド名 | シリアライザのフィールドであること |
| column | str | No | ファイルのカラム名 | ファイル内のカラムであること |

### 入力データソース

- 管理センター画面からのファイルアップロード
- REST API経由のマルチパートファイル送信

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pk | int | セッションID |
| status | int | インポートステータス |
| row_count | int | 総行数 |
| completed_row_count | int | 完了行数 |
| columns | list | ファイルのカラム一覧 |

### 出力先

- REST APIレスポンス（JSON）
- 管理センター画面への表示
- データベース（importer_dataimportsession, importer_dataimportcolumnmap, importer_dataimportrow）

## 処理フロー

### 処理シーケンス

```
1. ファイルアップロード
   └─ DataImportSession作成
2. カラム抽出
   └─ extract_columns()でカラム名抽出
3. 自動マッピング
   └─ フィールド名とカラム名の照合
4. マッピング確認
   └─ ユーザーによるマッピング調整
5. マッピング確定
   └─ accept_mapping()でインポート開始
6. データインポート
   └─ バックグラウンドタスクで実行
7. 結果確認
   └─ 行ごとのインポート結果表示
```

### フローチャート

```mermaid
flowchart TD
    A[ファイルアップロード] --> B[DataImportSession作成]
    B --> C[カラム抽出]
    C --> D[自動マッピング]
    D --> E[マッピング確認・調整]
    E --> F{必須フィールド全てマッピング?}
    F -->|No| E
    F -->|Yes| G[マッピング確定]
    G --> H[バックグラウンドタスク起動]
    H --> I[行ごとのデータ検証]
    I --> J[検証OK行のインポート]
    J --> K[結果確認]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-01 | 必須フィールドマッピング | 必須フィールドはマッピングまたはデフォルト値が必要 | マッピング確定時 |
| BR-39-02 | 一意性制約 | 同一カラムは複数フィールドにマッピング不可 | マッピング設定時 |
| BR-39-03 | 更新モード | update_records=trueの場合、ID指定で既存レコード更新 | インポート実行時 |
| BR-39-04 | 行検証 | 各行はシリアライザで検証される | データインポート時 |
| BR-39-05 | 空行スキップ | 完全に空の行はスキップ | データ読み込み時 |

### 計算ロジック

インポート進捗率:
```python
progress = completed_row_count / row_count * 100
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| セッション作成 | importer_dataimportsession | INSERT | セッション作成 |
| マッピング作成 | importer_dataimportcolumnmap | INSERT | カラムマッピング作成 |
| データ行作成 | importer_dataimportrow | INSERT | インポート行データ作成 |
| ステータス更新 | importer_dataimportsession | UPDATE | インポートステータス更新 |
| 対象テーブル | インポート先モデル | INSERT/UPDATE | 実データのインポート |

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

#### importer_dataimportsession

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | data_file, model_type, user_id, status | 入力値 | 初期ステータスはINITIAL |
| UPDATE | status | ステータスコード | MAPPING, IMPORTING, PROCESSING, COMPLETE |
| UPDATE | columns | カラム名リスト | extract_columns後 |

#### importer_dataimportrow

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | session_id, row_data, row_index, data | ファイルから抽出 | |
| UPDATE | valid, errors, complete | 検証結果 | |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 400 | ValidationError | 必須フィールド未マッピング | マッピングを完了する |
| 400 | ValidationError | 行データがバリデーション失敗 | データを修正して再インポート |
| 415 | UnsupportedMediaType | サポートされない形式 | CSV/Excel形式を使用 |

### リトライ仕様

- インポート処理はバックグラウンドタスクで実行
- 個別行のエラーは他の行に影響しない

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

- DataImportRowの一括作成はbulk_createで処理
- 各行のインポートは個別トランザクション
- エラー行は他の行に影響しない

## パフォーマンス要件

- カラム抽出：1秒以内
- データインポート：バックグラウンド処理
- 進捗表示：リアルタイム更新

## セキュリティ考慮事項

- アップロードファイルの拡張子制限
- ファイルサイズ制限
- インポート先モデルへの権限チェック

## 備考

DataImportStatusCode:
- INITIAL: 初期状態
- MAPPING: マッピング中
- IMPORTING: インポート実行中
- PROCESSING: 処理中
- COMPLETE: 完了

サポートされるファイル形式:
- CSV
- TSV
- XLS
- XLSX
- JSON

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

インポート機能のモデル定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | models.py | `src/backend/InvenTree/importer/models.py` | DataImportSession（28-397行目）の構造 |
| 1-2 | models.py | `src/backend/InvenTree/importer/models.py` | DataImportColumnMap（399-510行目）のマッピング定義 |
| 1-3 | models.py | `src/backend/InvenTree/importer/models.py` | DataImportRow（512-775行目）の行データ定義 |

**読解のコツ**:
- **28-41行目**: DataImportSessionのフィールド定義
- **69-82行目**: data_file, columns, model_typeフィールド
- **154-226行目**: extract_columns()でカラム抽出とマッピング作成
- **227-265行目**: accept_mapping()でマッピング確定とインポート開始
- **279-323行目**: import_data()でデータ読み込みと行データ作成

#### Step 2: エントリーポイントを理解する

REST APIエンドポイントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | api.py | `src/backend/InvenTree/importer/api.py` | DataImportSessionList, DataImportSessionDetail |
| 2-2 | api.py | `src/backend/InvenTree/importer/api.py` | DataImportColumnMapDetail |
| 2-3 | api.py | `src/backend/InvenTree/importer/api.py` | DataImportRowList, DataImportRowDetail |

#### Step 3: バックグラウンド処理を理解する

インポートタスクの処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tasks.py | `src/backend/InvenTree/importer/tasks.py` | import_dataタスク |

#### Step 4: データ操作を理解する

ファイル読み込みと変換処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | operations.py | `src/backend/InvenTree/importer/operations.py` | extract_column_names(), load_data_file() |

### プログラム呼び出し階層図

```
DataImportSessionList.create()
    │
    ├─ DataImportSession作成
    │      └─ save()
    │             └─ extract_columns()
    │                    ├─ operations.extract_column_names()
    │                    └─ DataImportColumnMap.bulk_create()
    │
    └─ status = MAPPING

DataImportSession.accept_mapping()
    │
    ├─ 必須フィールドチェック
    │
    └─ trigger_data_import()
           └─ offload_task(importer.tasks.import_data)

importer.tasks.import_data(session_pk)
    │
    └─ session.import_data()
           ├─ operations.load_data_file()
           ├─ DataImportRow.bulk_create()
           └─ status = PROCESSING

DataImportRow.validate(commit=True)
    │
    ├─ construct_serializer()
    │      └─ serializer.is_valid()
    │
    └─ serializer.save()
           └─ complete = True
```

### データフロー図

```
[入力]                    [処理]                           [出力]

ファイル ───▶ アップロード ───▶ DataImportSession
   │                              │
   │                              ▼
   │                       extract_columns() ───▶ columns
   │                              │
   │                              ▼
   │                       DataImportColumnMap ───▶ マッピング
   │                              │
   │                              ▼
   │                       accept_mapping() ───▶ タスク起動
   │                              │
   │                              ▼
   │                       import_data() ───▶ DataImportRow
   │                              │
   │                              ▼
   │                       validate() ───▶ インポート先モデル
   │                              │
   └──────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| models.py | `src/backend/InvenTree/importer/models.py` | ソース | インポートモデル定義 |
| api.py | `src/backend/InvenTree/importer/api.py` | ソース | インポートAPI |
| serializers.py | `src/backend/InvenTree/importer/serializers.py` | ソース | シリアライザ |
| tasks.py | `src/backend/InvenTree/importer/tasks.py` | ソース | バックグラウンドタスク |
| operations.py | `src/backend/InvenTree/importer/operations.py` | ソース | ファイル操作 |
| validators.py | `src/backend/InvenTree/importer/validators.py` | ソース | バリデータ |
| registry.py | `src/backend/InvenTree/importer/registry.py` | ソース | サポートモデル登録 |
| status_codes.py | `src/backend/InvenTree/importer/status_codes.py` | ソース | ステータスコード定義 |
