💨

コーディング支援AIでCSVファイルを読みこみテーブルに保存、表示する際の注意点

に公開

今回作っているプロジェクトで、CSVファイルの内容を読みこみ、データベースのテーブルに保存、表示の工程が完成できず、数週間費やすことになってしまいました。
今回の反省で、原因とそれを防ぐプロンプトをGPT-5に作ってもらいました。
次回の自分の参考になるように備忘録の意味も込めて、作成しました。

Claude Codeやcursor、WindsurfなどでCSVを扱うときの注意

コーディング支援AIを使ってCSVファイルの読み込みの工程のコードを作成するとき、AIに丸投げすると、大事件になってしまい完成しないことがあります。
CSVファイルを扱うときに、今回起きた問題点

  • CSVファイルのカラム名が日本語なのに、英語に勝手に変えてしまう。
  • カラム名が英語なので、マッピングを作ろうとする
  • CSVファイルのカラムの順番に処理せず計算して順番を勝手に決めてしまう
  • CSVファイルのカラムのデータが無いときに、安全装置で別のソースからデータを補充しようとする

これらのような問題が発生するため、簡単にできるはずのCSVのファイルの読み込みができない時があります。

CSVファイルの構造は簡単に変わらない

CSVファイルの構造、カラム名などは、よほどのことが無い限り変らないと思ってよいと思うのです。
だから、CSVファイルのカラム名をCSVファイルから動的に読みこむことは良いことですが、その読み取ったカラム名が正しく使われるように、プロンプトを工夫する必要があります。

コーディング支援AIは、CSVファイルのカラム名とエクセルのBookで使われている項目名と一致させるために、マッピングを作ることがあります
でも基本的に作業現場で、CSVファイルの内容をコピーして、そのままExcelのシートに張り付得ているとき、項目などの並び順は、CSVファイルの順番と同じはずです。
そのため、コーディング支援AIが難しく考えすぎてしまい、コーディングできなくなることを防ぐために、プロンプトが必要と思います。

GPT-5に作てもらったプロンプト

今回の反省を基に、プロンプトを作ってもらいました。
プロジェクトの内容に合わせて、修正して使うことができます。

基本原則(毎回の前置きとして)

  • CSVのカラム名・順序・データ型を絶対に変更しない。英語化・スネークケース化・並べ替え・別名付与を禁止。

  • スキーマはCSVのヘッダーをそのまま採用。型は推測せず、私が指定した型以外では作らない。

  • 変換は必要最小限(トリム・空白正規化・NULL整備など)のみ。列の追加・削除・分割・結合は禁止。

  • 文字コード・区切り文字・クオート・改行コード・BOMの扱いを最初に宣言してから実装。

  • 検証(レコード件数一致、ハッシュ/サンプル一致)を必ず行い、差異は一覧化。

1) CSVを読む前の指示プロンプト(共通テンプレ)

あなたはコーディング支援AIです。以下のルールを厳守して、CSV→DB→表示の実装方針とコードを提案してください。

【入力CSVの仕様】
- ファイルパス: [./data/xxx.csv]
- 文字コード: [UTF-8 / Shift_JIS](BOM: [有/無])
- 区切り文字: [,] / クオート: ["] / 改行: [LF/CRLF]
- 1行目はヘッダー。**このヘッダー名と列順を絶対に変更しない**。
- 欠損は空文字→NULLに正規化。ただし列の追加・削除・並べ替えは禁止。

【DB仕様】
- DB種別: [PostgreSQL/MySQL/SQLite]
- 接続情報: [環境変数/ダミーでOK]
- テーブル名: [raw_xxx]
- カラム定義: CSVヘッダーをそのまま列名に採用。型は以下のみ使用:
  [列名A: TEXT, 列名B: INTEGER, 列名C: NUMERIC(18,2), 列名D: DATE …]
- 主キー/一意制約: [列名](なければ無し)
- 取り込みはトランザクション+UPSERT(主キー重複は更新、それ以外は挿入)

【実装要件】
- 言語/ランタイム: [Python3 + pandas + SQLAlchemy](例)
- **列名のリネーム・翻訳・順序変更・自動型推測による型変更は絶対禁止**。
- 大容量対応: [チャンクサイズ=50,000行]で分割ロード(必要なら)。
- ログ出力: 開始/終了時刻、読み取り件数、挿入件数、更新件数、スキップ件数、エラー件数。
- バリデーション: 
  1) CSV行数とDB取り込み後行数の一致チェック
  2) ランダムn件(n=10)のレコードをCSVとDBで値一致検証
  3) 列名・順序がCSVと完全一致することを確認

【出力物】
1) 実行手順(コマンド) 
2) 完整なコード
3) バリデーション手順と期待結果
4) よくあるエラーと対処

2) スキーマ生成だけを指示するプロンプト

CSVのヘッダーを**そのまま**列名として使い、指定型でテーブルを作成するSQLを出力してください。列名や順序を変えないでください。追加・削除・別名は禁止。

入力:
- テーブル名: [raw_orders]
- 列と型:
  - [受注番号]: TEXT
  - [注文日]: DATE
  - [商品名]: TEXT
  - [数量]: INTEGER
  - [金額]: NUMERIC(18,2)

要件:
- [PostgreSQL]構文でCREATE TABLE IF NOT EXISTS
- 文字列列はTEXT固定、金額はNUMERIC(18,2)
- 主キー: [受注番号]
- そのままCOPY/LOADできるようカラム順をヘッダー順で定義

3) 取り込み(ETL)を指示するプロンプト


以下の条件でCSV→DBに取り込むコードを書いてください。

前提:
- 言語: [Python]
- ライブラリ: pandas, SQLAlchemy
- CSV: [./data/orders.csv] / エンコーディング[UTF-8] / 区切り[,] / クオート["] / 改行[LF]
- テーブル: [raw_orders]
- 列名・順序はCSVどおり。**rename禁止**。

要件:
- チャンク読み込み(例: chunksize=50_000)
- 欠損は空文字→NULL
- 数量は整数、金額はDecimalにキャスト。失敗行は隔離(error_rows.csvへ出力)
- UPSERT(主キー[受注番号])。競合時は[数量, 金額]のみ更新
- トランザクションで一括コミット
- ログ出力&進捗表示

最後に、取り込み件数、更新件数、スキップ件数のサマリーと、列名・順序の一致確認ロジックを含めてください。

4) 表示(API/画面)を指示するプロンプト

DBテーブル[raw_orders]を読み取り、以下の仕様で表示用API(もしくは簡易UI)を実装してください。

要件:
- 列名は**DBの日本語列名のまま**返す(キーも日本語)。英語化禁止。
- デフォルトソート: [注文日 DESC, 受注番号 ASC]
- ページング: page/limit形式
- フィルタ: [注文日範囲, 金額範囲, 商品名の部分一致]
- 集計エンドポイント: [合計金額, 注文件数, 平均単価]
- レスポンス例を提示し、列順はDBと同一にすること


5) 検証・テスト用のプロンプト

次を行うテストコードと手順を出力してください。

- 列名・順序の完全一致テスト(CSVヘッダー配列とDBメタデータの配列比較)
- レコード件数一致テスト
- サンプル10件のランダム抽出→CSVとDBで全列一致(NULL/空文字の等価扱いルール明記)
- 金額の合計値がCSVとDBで一致
- エンコーディング/改行/BOM差異の回避テスト

すべて自動化し、成功/失敗を明示。失敗時は行番号と差分を表で出力してください。


6) 追加の安全装置を要求するプロンプト

取り込み時の安全策を追加してください。

- ドライラン(--dry-run)オプション: 実際に書き込まず件数とサマリーのみ出力
- トランケート禁止。既存データは保持
- バックアップ(EXPORT)機能: 取り込み前に全件をCSVへエクスポート
- 再実行しても重複しないようUPSERT徹底
- ログを日付別ファイルにローテーション


7) 既存コードの“勝手リネーム”を防ぐチェックプロンプト

これからあなたが出力するコードでは、次のことを**絶対にしない**でください:
- 列名の翻訳(日本語→英語など)
- 列順の変更
- 自動型推測による列型の変更
- 列の追加/削除/結合/分割

違反がないか、あなたの出力を自己点検し、禁則に触れる箇所があれば修正したうえで最終コードを出力してください。

8) トラブル時のデバッグ用プロンプト


次の現象の原因切り分けと対策を、チェックリスト形式で出してください。

現象: 「表示で列名が英語に変わる/順序が崩れる」

観点:
- CSV読込時のrename/columns指定の有無
- DataFrame保存時にcolumnsソート・再配置していないか
- ORMのモデル定義で英語名を付けていないか
- マイグレーションで列追加/リネームが混ざっていないか
- API層でレスポンスキーを英語化していないか
- シリアライザ/スキーマ自動生成で列名マッピングが動いていないか
- ビュー層(JS/TS)でプロパティ名を変換していないか

対策は「具体的な設定名・コード差分」で提示し、再発防止策(スナップショットテスト、スキーマ固定化)も挙げてください。

まとめ

CSVファイルの読み込みの工程のコードをAIを使って行うときは、プロンプトで、規則、条件などの仕様などを繰り返し根気強く伝えて、実現できるように工夫することが大切だと思います。
そして、AIに丸投げではなく、自分自身で内容を理解して、実際のCSVのカラム名やExcelのカラム名の確認など基本的な作業を行いましょう。

追記

ようやくプロジェクトで、CSVからインポートして、データベースのテーブルに保存し、表示の一連の流れができました。
https://x.com/masaru21/status/1969637129618932033
今回分かったことは、AIに繰り返し基本に立ち返り、先頭からデータを読むように、繰り返し理解できるまで伝えることです。
CSVでヘッダーが動的に位置が変わるなんて、あり得ないです。
だから、AIの言って来ることを鵜呑みにしないで、自分で検証してください。
そしてAIに丸投げしないで、自分でExcelの列の状況を確認したり、CSVのヘッダーの状況、データの型も、確認しましょう。
私も、こんな簡単なことで、なぜここまえトラブるのか、謎に思っています。
とにかくAIでCSVを使うプログラムを作るときは。先頭からデータを読みこむことを基本にして、何があっても、AIに伝え続けてください。

Discussion