Skip to content

Commit 09e954b

Browse files
authored
DBを分離する - PostgreSQL移行設計書 (#114)
1 parent 68d5bcc commit 09e954b

1 file changed

Lines changed: 239 additions & 0 deletions

File tree

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# データベース分離設計書
2+
3+
## 1. 概要
4+
5+
### 1.1 目的
6+
タスク情報の永続化層をSQLiteからPostgreSQLに移行し、SQLAlchemyを使用してデータベースアクセスを汎用化する。
7+
8+
### 1.2 対象範囲
9+
- **タスク情報DB(tasksテーブル)のみ**を対象とする
10+
- メッセージ履歴、要約履歴、ツール実行履歴(JSONLファイル)は対象外
11+
12+
### 1.3 TaskKey構造の分析
13+
現在のTaskKeyは以下の4種類があり、それぞれ異なるフィールドを持つ:
14+
15+
| TaskKey種別 | task_source | task_type | owner | repo | project_id | number |
16+
|------------|-------------|-----------|-------|------|------------|--------|
17+
| GitHubIssueTaskKey | github | issue ||| - ||
18+
| GitHubPullRequestTaskKey | github | pull_request ||| - ||
19+
| GitLabIssueTaskKey | gitlab | issue | - | - || ○(issue_iid) |
20+
| GitLabMergeRequestTaskKey | gitlab | merge_request | - | - || ○(mr_iid) |
21+
22+
これらを統一的に扱うため、以下のフィールド構成でtask_keyを分解する:
23+
- `task_source`: タスクソース(github/gitlab)
24+
- `task_type`: タスクタイプ(issue/pull_request/merge_request)
25+
- `owner`: GitHubリポジトリオーナー(GitLabの場合はNULL)
26+
- `repo`: GitHubリポジトリ名(GitLabの場合はNULL)
27+
- `project_id`: GitLabプロジェクトID(GitHubの場合はNULL)
28+
- `number`: タスク番号(GitHub: number、GitLab: issue_iid/mr_iid)
29+
30+
---
31+
32+
## 2. 詳細設計
33+
34+
### 2.1 ファイル構成
35+
1ファイルにDBTaskモデルとDBアクセスロジックをまとめる:
36+
37+
```
38+
db/
39+
└── task_db.py # DBTaskモデル定義 + TaskDBManagerクラス
40+
```
41+
42+
### 2.2 task_db.py の設計
43+
44+
#### 2.2.1 DBTask モデル
45+
SQLAlchemy ORMを使用してtasksテーブルを定義する。
46+
47+
**処理内容**:
48+
- SQLAlchemy 2.0スタイルの宣言的ベースクラスを使用する
49+
- PostgreSQL用の型定義を行う
50+
- task_key分解フィールドのインデックスを定義する
51+
- `get_task_key()` メソッドでTaskKeyオブジェクトを復元する
52+
53+
**カラム定義**:
54+
| カラム名 || PostgreSQL型 | 制約 | 説明 |
55+
|---------|-----|-------------|------|------|
56+
| uuid | String(36) | VARCHAR(36) | PRIMARY KEY | タスク一意識別子 |
57+
| task_source | String(50) | VARCHAR(50) | NOT NULL | タスクソース(github/gitlab) |
58+
| task_type | String(50) | VARCHAR(50) | NOT NULL | タスクタイプ(issue/pull_request/merge_request) |
59+
| owner | String(255) | VARCHAR(255) | NULL可 | GitHubリポジトリオーナー |
60+
| repo | String(255) | VARCHAR(255) | NULL可 | GitHubリポジトリ名 |
61+
| project_id | Integer | INTEGER | NULL可 | GitLabプロジェクトID |
62+
| number | Integer | INTEGER | NOT NULL | タスク番号 |
63+
| status | String(20) | VARCHAR(20) | NOT NULL | ステータス |
64+
| created_at | DateTime | TIMESTAMP WITH TIME ZONE | NOT NULL | 作成日時 |
65+
| started_at | DateTime | TIMESTAMP WITH TIME ZONE | - | 開始日時 |
66+
| completed_at | DateTime | TIMESTAMP WITH TIME ZONE | - | 完了日時 |
67+
| process_id | Integer | INTEGER | - | プロセスID |
68+
| hostname | String(255) | VARCHAR(255) | - | ホスト名 |
69+
| llm_provider | String(50) | VARCHAR(50) | - | LLMプロバイダー |
70+
| model | String(100) | VARCHAR(100) | - | 使用モデル |
71+
| context_length | Integer | INTEGER | - | コンテキスト長 |
72+
| llm_call_count | Integer | INTEGER | DEFAULT 0 | LLM呼び出し回数 |
73+
| tool_call_count | Integer | INTEGER | DEFAULT 0 | ツール呼び出し回数 |
74+
| total_tokens | Integer | INTEGER | DEFAULT 0 | 総トークン数 |
75+
| compression_count | Integer | INTEGER | DEFAULT 0 | 圧縮回数 |
76+
| error_message | Text | TEXT | - | エラーメッセージ |
77+
| user | String(255) | VARCHAR(255) | - | ユーザー名 |
78+
79+
**インデックス定義**:
80+
| インデックス名 | カラム | 用途 |
81+
|--------------|--------|------|
82+
| ix_tasks_status | status | ステータス別検索の高速化 |
83+
| ix_tasks_created_at | created_at | 作成日時順ソートの高速化 |
84+
| ix_tasks_user | user | ユーザー別検索の高速化 |
85+
| ix_tasks_task_key | task_source, task_type, owner, repo, project_id, number | TaskKey検索の高速化 |
86+
87+
**DBTaskモデルのメソッド**:
88+
| メソッド名 | 引数 | 戻り値 | 説明 |
89+
|-----------|------|--------|------|
90+
| get_task_key | - | TaskKey | task_key分解フィールドからTaskKeyオブジェクトを復元する |
91+
92+
#### 2.2.2 TaskDBManager クラス
93+
タスクのDB操作を行うロジッククラスを実装する。
94+
95+
**初期化処理**:
96+
- 環境変数またはconfig.yamlからPostgreSQL接続情報を取得する
97+
- SQLAlchemyエンジンを作成する
98+
- セッションファクトリーを初期化する
99+
100+
**接続設定**:
101+
| 環境変数名 | 説明 | デフォルト値 |
102+
|-----------|------|------------|
103+
| DATABASE_HOST | PostgreSQLホスト | localhost |
104+
| DATABASE_PORT | PostgreSQLポート | 5432 |
105+
| DATABASE_NAME | データベース名 | coding_agent |
106+
| DATABASE_USER | ユーザー名 | - |
107+
| DATABASE_PASSWORD | パスワード | - |
108+
| DATABASE_URL | 完全な接続URL(他設定を上書き) | - |
109+
110+
**メソッド定義**:
111+
112+
| メソッド名 | 引数 | 戻り値 | 説明 |
113+
|-----------|------|--------|------|
114+
| create_task | task_data: dict | DBTask | 新規タスクを作成し、DBにINSERTする |
115+
| create_task_from_task | task: Task | DBTask | Taskオブジェクトから新規タスクを作成し、DBにINSERTする |
116+
| get_task | uuid: str | DBTask または None | UUIDでタスクを取得する |
117+
| get_task_by_key | task_key: TaskKey | DBTask または None | TaskKeyでタスクを取得する |
118+
| save_task | db_task: DBTask | DBTask | DBTaskオブジェクトを保存(更新)する |
119+
120+
**処理内容**:
121+
- セッション管理をコンテキストマネージャーで自動化する
122+
- 例外発生時の自動ロールバックを実装する
123+
- ログ出力によるデバッグ支援を提供する
124+
125+
### 2.3 既存コード修正設計
126+
127+
#### 2.3.1 TaskContextManager の修正(context_storage/task_context_manager.py)
128+
現在のSQLite直接操作を、TaskDBManagerクラスを使用したアクセスに変更する。
129+
130+
**修正対象メソッド**:
131+
| メソッド | 修正内容 |
132+
|---------|---------|
133+
| `__init__` | TaskDBManagerクラスのインスタンスを作成する |
134+
| `_init_database` | 削除。初期化はTaskDBManagerクラスで行う |
135+
| `_register_or_update_task` | TaskDBManager.create_task または TaskDBManager.save_task を使用する |
136+
| `update_status` | DBTaskオブジェクトを取得し、ステータスを変更後、save_taskを使用する |
137+
| `update_statistics` | DBTaskオブジェクトを取得し、統計情報を更新後、save_taskを使用する |
138+
| `complete` | DBTaskオブジェクトを取得し、完了状態に変更後、save_taskを使用する |
139+
| `stop` | DBTaskオブジェクトを取得し、停止状態に変更後、save_taskを使用する |
140+
| `fail` | DBTaskオブジェクトを取得し、失敗状態に変更後、save_taskを使用する |
141+
142+
### 2.4 設定ファイル設計
143+
144+
#### 2.4.1 config.yaml への追加
145+
以下の設定セクションを追加する:
146+
147+
```yaml
148+
# データベース設定
149+
database:
150+
# PostgreSQL設定
151+
host: "localhost"
152+
port: 5432
153+
name: "coding_agent"
154+
user: ""
155+
password: ""
156+
157+
# コネクションプール設定
158+
pool_size: 5
159+
max_overflow: 10
160+
```
161+
162+
### 2.5 DB作成ツール
163+
データベースとテーブルを作成するコマンドラインツールを提供する。
164+
165+
**ファイル**: `scripts/create_db.py`
166+
167+
**処理内容**:
168+
- PostgreSQLに接続する
169+
- tasksテーブルが存在しない場合は作成する
170+
- インデックスを作成する
171+
172+
**使用方法**:
173+
```bash
174+
python scripts/create_db.py
175+
```
176+
177+
---
178+
179+
## 3. Docker環境設計
180+
181+
### 3.1 docker-compose.yml への追加
182+
PostgreSQLコンテナを追加する。
183+
184+
**サービス定義**:
185+
- サービス名: `postgres`
186+
- イメージ: `postgres:16`
187+
- ボリューム: データ永続化用ボリューム
188+
- 環境変数: DB名、ユーザー名、パスワード
189+
- ヘルスチェック: pg_isready コマンド
190+
191+
### 3.2 依存関係設定
192+
既存のサービス(producer、consumer等)にPostgreSQLへの依存を追加する。
193+
194+
**処理内容**:
195+
- `depends_on` に postgres サービスを追加する
196+
- ヘルスチェック完了を待機する設定を追加する
197+
198+
---
199+
200+
## 4. 依存関係
201+
202+
### 4.1 追加パッケージ
203+
以下のパッケージを追加する:
204+
205+
| パッケージ名 | バージョン | 用途 |
206+
|-------------|----------|------|
207+
| sqlalchemy | >=2.0.0 | ORM・DB抽象化 |
208+
| psycopg2-binary | >=2.9.0 | PostgreSQLドライバ |
209+
210+
### 4.2 pyproject.toml / condaenv.yaml への追加
211+
上記パッケージを依存関係に追加する。
212+
213+
---
214+
215+
## 5. 影響範囲
216+
217+
### 5.1 修正対象ファイル
218+
| ファイル | 修正内容 |
219+
|---------|---------|
220+
| context_storage/task_context_manager.py | DB操作をTaskDBManagerクラス経由に変更 |
221+
| config.yaml | database セクションを追加 |
222+
| docker-compose.yml | postgres サービスを追加 |
223+
| pyproject.toml | 依存パッケージを追加 |
224+
| condaenv.yaml | 依存パッケージを追加 |
225+
226+
### 5.2 新規作成ファイル
227+
| ファイル | 内容 |
228+
|---------|------|
229+
| db/task_db.py | DBTaskモデル + TaskDBManagerクラス |
230+
| scripts/create_db.py | DB作成ツール |
231+
232+
---
233+
234+
## 6. 用語集
235+
236+
| 用語 | 説明 |
237+
|------|------|
238+
| ORM | Object-Relational Mapping。オブジェクトとリレーショナルデータベースの間のマッピング |
239+
| コネクションプール | データベース接続を再利用するための接続プール |

0 commit comments

Comments
 (0)