Skip to content

Commit dc10ec5

Browse files
committed
docs: Add plan (#2785)
1 parent c7752de commit dc10ec5

File tree

1 file changed

+115
-0
lines changed
  • docs/dev-notes/2025-11-03/import-contest-task-pair-to-supabase

1 file changed

+115
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Supabase に CSV からデータをインポートする方法
2+
3+
## 基本的な手順
4+
5+
### 1. CSV ファイルの準備
6+
7+
Supabase Dashboard からのインポートでは、以下のカラムを **必ず含める** 必要があります:
8+
9+
- `id` - UUID(自動生成ではなく、CSV に含める必要がある)
10+
- `createdAt` - タイムスタンプ
11+
- `updatedAt` - タイムスタンプ
12+
- その他のビジネスロジック用カラム
13+
14+
**CSV ファイルの例(`contest_task_pairs.csv`):**
15+
16+
```csv
17+
id,contestId,taskId,taskTableIndex,createdAt,updatedAt
18+
550e8400-e29b-41d4-a716-446655440000,tessoku-book,typical90_s,C18,2025-11-03T10:00:00.000Z,2025-11-03T10:00:00.000Z
19+
6ba7b810-9dad-11d1-80b4-00c04fd430c8,tessoku-book,math_and_algorithm_ac,C09,2025-11-03T10:00:00.000Z,2025-11-03T10:00:00.000Z
20+
7cb12b42-0b4a-11d2-91c5-00d04fd430c9,tessoku-book,abc007_3,B63,2025-11-03T10:00:00.000Z,2025-11-03T10:00:00.000Z
21+
```
22+
23+
### 2. Python で UUID と タイムスタンプを生成
24+
25+
既存の CSV に `id``createdAt``updatedAt` を追加するスクリプト:
26+
27+
```python
28+
import uuid
29+
import csv
30+
from datetime import datetime
31+
32+
# 現在時刻を ISO 8601 形式で取得
33+
now = datetime.utcnow().isoformat() + 'Z'
34+
35+
# CSV を読み込み
36+
with open('tessoku-book.csv', 'r') as f:
37+
reader = csv.reader(f)
38+
header = next(reader)
39+
rows = list(reader)
40+
41+
# ID とタイムスタンプを追加して新しい CSV を作成
42+
with open('tessoku-book-with-id.csv', 'w', newline='') as f:
43+
writer = csv.writer(f)
44+
writer.writerow(['id', 'createdAt', 'updatedAt'] + header)
45+
46+
for row in rows:
47+
writer.writerow([str(uuid.uuid4()), now, now] + row)
48+
49+
print(f"{len(rows)} 件のデータを処理しました")
50+
```
51+
52+
### 3. Supabase Dashboard からインポート
53+
54+
1. [Supabase ダッシュボード](https://supabase.com/dashboard)にログイン
55+
2. 対象のプロジェクト → 「SQL Editor」または「Table Editor」を選択
56+
3. 対象テーブル(例:`contesttaskpair`)を選択
57+
4. 右上の「Import data」または「↓ Import」ボタンをクリック
58+
5. 生成した CSV ファイル(`tessoku-book-with-id.csv`)を選択
59+
6. カラムのマッピングを確認
60+
7. 「Import」をクリック
61+
62+
## トラブルシューティング
63+
64+
### エラー: "null value in column "id" violates not-null constraint"
65+
66+
**原因:** CSV に `id` カラムが含まれていない場合、Supabase が自動生成してくれません。
67+
68+
**解決方法:** 上記の Python スクリプトを使用して、UUID を生成した CSV を作成してください。
69+
70+
### エラー: カラム名が一致しない
71+
72+
**原因:** CSV のカラム名とテーブルの属性名が異なる
73+
74+
**対応:**
75+
76+
- CSV のカラム名とテーブルの属性名が完全に一致していることを確認
77+
- インポート画面でカラムマッピングを手動で行う
78+
- 大文字小文字は区別されるので注意
79+
80+
### CSV のカラム順序が異なる場合
81+
82+
**結果:** 問題ありません。Supabase はカラム名で識別するため、順序は関係ありません。
83+
84+
## 得られた教訓
85+
86+
### 1. 自動生成カラムについて
87+
88+
Prisma スキーマで `@default(uuid())``@default(now())` が定義されていても、Supabase Dashboard の CSV インポート機能はこのデフォルト値を適用しません。
89+
90+
```prisma
91+
model ContestTaskPair {
92+
id String @id @default(uuid()) // ← デフォルト値が定義されていても
93+
createdAt DateTime @default(now()) // ← CSV インポートには反映されない
94+
updatedAt DateTime @updatedAt
95+
}
96+
```
97+
98+
**対策:** CSV ファイルに明示的にこれらのカラムを含める必要があります。
99+
100+
### 2. カラム名の一致は必須
101+
102+
- **必須:** CSV のカラム名 = テーブルの属性名
103+
- **不要:** カラムの順序
104+
- **補完:** インポート画面でマッピングできるが、あらかじめ一致させておくのが確実
105+
106+
### 3. UUID v4 の選択
107+
108+
デフォルトの `uuid()` (v4) はランダムなため、DB インデックスの効率が低下します。大規模なデータセットの場合は、`cuid()` の使用や UUID v6 の検討を推奨します。
109+
110+
## 参考資料
111+
112+
- [Supabase 公式 - Import data](https://supabase.com/docs/guides/database/import-data)
113+
- [Prisma - @default 関数](https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#default)
114+
- [RFC 9562 - UUID Versions](https://tools.ietf.org/html/rfc9562)
115+
- [UUID Library for Python - uuid4](https://docs.python.org/3/library/uuid.html#uuid.uuid4)

0 commit comments

Comments
 (0)