本文へ移動

技術ガイド

CSVをSupabaseにインポートする方法

SupabaseのTable EditorまたはPostgreSQLのCOPYでインポートし、列の値を決定する主体、テナントのコンテキスト、制約、取り込み結果を確認します。

Mohamed Atef · ImportFlow
最終レビュー

少量の準備済みCSVなら、SupabaseのTable Editorで取り込み先のテーブルを開き、Insert → Import Data from CSVを選択します。ファイルを選び、インポート内容を確認してから確定してください。新しいテーブルを作る場合は、New tableからCSVインポートのオプションを使用します。現在、ダッシュボードのドキュメントでは上限が100MBとされています。

開発用データセットや、管理者が条件を管理できるインポートでは、多くの場合これで十分です。既存のアプリケーションに顧客のエクスポートファイルを取り込む場合は、各フィールドの意味が取り込み先の想定と一致するか、先に確認してください。アップロードに成功しても、連絡先がどのテナントに属するか、旧システムのアカウント番号がアプリ内でも同じアカウントを指すかは判断できません。

利用できる取り込み方法は、Supabaseの公式インポートガイドに記載されています。本ガイドでは、顧客データを一度だけインポートする際に必要な判断を順に解説します。

対象範囲と前提条件. Supabaseダッシュボードの操作手順は2026年9月13日に確認しました。SQLの例はPostgreSQL 17を対象とし、架空のデータを使用しています。

要件を満たす最小限のインポート方法を選ぶ

状況最初に検討する方法引き続き自分で担う責任
ファイルが小さく、列が既知で、管理者が作業するTable EditorのCSVインポート取り込み先、入力値、結果の確認
SQLを十分にレビューして行う、一度限りのインポートpsqlとCOPY。必要に応じてステージングを経由接続権限、マッピング、トランザクション、検証
アプリケーションユーザーの権限でインポートする必要がある意図したロールでのアプリケーションAPI/INSERT認可、リクエストの制限、エラー処理
顧客がさまざまな形式のエクスポートを定期的に持ち込む再利用可能なインポーターマッピングのUX、ジョブ、復旧、サポート

一度限りのスクリプトも妥当な中間案です。入力形式を明示し、事前に試行し、何が起きたかを判断できる証拠を残してください。エンジニアが一度だけ実行するインポートなら、通常はレビュー済みのスクリプトで十分です。

顧客が繰り返しファイルをアップロードする場合は、CSVインポーターのアーキテクチャチェックリストを参照してください。以降は、エンジニアが特定のインポートを準備することを前提に進めます。

既存テーブルに合わせてファイルを準備する

エクスポートファイルのコピーを使って作業を始めます。修正の経緯を説明できるよう、原本は保存してください。区切り文字、文字エンコーディング、ヘッダー行、空欄の意味を記録します。外部識別子のフィールドは、見える値がすべて数字でもテキストとして扱ってください。

連絡先テーブルでは、承認済みの入力データに次の2つのフィールドだけが含まれている場合があります。

CSV
email,display_name
first@example.test,First Contact
second@example.test,"Second, Contact"

引用符で囲まれたカンマは、2件目の連絡先の名前の一部です。各行をカンマで分割すると、3つ目のフィールドができてしまいます。引用符で囲まれたフィールドには改行も含められるため、物理的な行数を数えてもレコード数を正確には把握できません。

インポート前に、重複するヘッダーとマッピングを確認します。「Email」という入力列が2つある場合は、どちらを使うか明示的に選ぶ必要があります。余分な列も、判断したうえで除外してください。ファイル内のid、tenant_id、created_atは、名前が一致するという理由だけで書き込み可能と判断してはいけません。

ExcelやGoogle Sheetsから始める場合

対象のワークシートをUTF-8のCSVとしてエクスポートし、同じ方法でインポートします。Google Sheetsでは、現在のシートに対してFile → Download → Comma-separated valuesを使用します。Excelでは、CSV UTF-8形式でコピーを保存してください。ワークブックには複数のシートを含められますが、CSVが表すのは1つの平坦なテーブルです。XLSXファイルの拡張子をCSVに変えても変換にはなりません。

アップロード前に、エクスポートしたテキストを確認します。先頭にゼロが付く識別子、日付、小数、数式から求めたセルを確認してください。表計算ソフトがすでに00042を42に変えていた場合、UTF-8でエクスポートしても失われたゼロは復元できません。元のデータに戻るか、承認済みの修正値を入手します。

04/05/2026のような日付は、データの管理責任者に意味を確認します。4月5日なのか5月4日なのかを推測してはいけません。タイムスタンプについては、意図するタイムゾーンを記録してください。日付だけで表す記念日に、誤ってタイムゾーン変換を適用しないようにします。更新され続けるシートとの継続的な同期は、今回の一度限りのエクスポートとは別の要件です。

取り込み先の要件を確認する

最初の書き込み前に、各フィールドの値を誰が決定するかを簡潔に整理します。たとえば、メールアドレスと表示名は承認済みの入力データ、テナントは認可済みのアプリケーションコンテキスト、IDはPostgreSQL、監査用タイムスタンプはアプリケーションで決めた規則に従う、といった整理です。

通常のデフォルト値は、入力データから値を指定することを禁止しません。生成式はそれとは異なります。また、列の省略、明示的なNULL、空文字列では結果が異なることがあります。デフォルト値と生成値のガイドで、その違いを実例で確認できます。

マイグレーションSQLやDDLがある場合は、PG Import Checkで取り込み先テーブルの要件を確認できます。対応している構造上の宣言を、ブラウザー内でローカルに解析して報告します。実際の行の調査、CSVの検証、実効的なRLSの判定、本番インポートの承認は行いません。入力した定義と実際にデプロイされているスキーマの整合性は、自分で確認してください。

psqlで列リストを明示してインポートする

この小規模な事前検証では、使い捨てのPostgreSQL 17データベース内に一時テーブルを作成します。アプリケーションのテーブルに触れずに、CSVの取り込み動作を確認できます。接続済みのpsqlセッションで、テーブルを作成してください。

SQL
CREATE TEMP TABLE import_contacts_demo (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  email text NOT NULL UNIQUE,
  display_name text,
  created_at timestamptz NOT NULL DEFAULT now()
);

上記のCSVをクライアントの作業ディレクトリにcontacts.csvとして保存し、次のコマンドをpsqlで1行で実行します。

psql
\copy import_contacts_demo (email, display_name) FROM 'contacts.csv' WITH (FORMAT csv, HEADER MATCH, ENCODING 'UTF8')
SQL
SELECT id, email, display_name, created_at
FROM import_contacts_demo
ORDER BY id;

2行が作成され、それぞれに異なるIDが生成され、2件目の名前にカンマが保持され、データベース側のタイムスタンプが設定されることを確認します。列リストを明示しているため、IDとタイムスタンプの生成はデータベースに任せられます。PostgreSQL 17のHEADER MATCHは、列名と順序を検査します。単なるHEADER trueはヘッダーを読み飛ばすだけで、名前による値のマッピングは行いません。

psqlのバックスラッシュ付きcopyコマンドは、クライアントマシン上のファイルを読み、データベース接続を通じて送信します。サーバー側のCOPY FROM '/path'は、データベースサーバーのファイルシステムを読み取ります。この方法でSupabaseが手元のノートPCのパスを読むことはできません。

実際にSupabaseへ接続する際は、プロジェクトの接続手順から、正しいエンドポイントとSSL設定を取得してください。保存するコマンド、Git、スクリーンショットにパスワードを含めないでください。実行ロールと接続モードはデータベースの管理責任者に選んでもらいます。この一時テーブルの例で、本番環境の権限が確立されるわけではありません。

正規化と失敗時の動作を事前に検証する

顧客のファイルには、列挙型がactiveを要求する箇所に「Active account」のようなラベルが入っていることがあります。ステージング用の表現を使えば、元の値、変換候補、変更理由を並べて保持できます。この対応付けは業務上の責任者が承認し、インポーターが一貫して適用します。

ステージングには、一時テーブル、別の使い捨てデータベース、長時間のジョブ向けにアクセスを制限した永続領域などを使えます。データの機密性と復旧要件に応じて選択してください。アプリケーションAPI経由で公開される、保護されていないテーブルにしてはいけません。本番に関係する制約と書き込み動作を隔離環境で検証し、事前検証では再現できない点を記録します。

PostgreSQLのCOPYは、デフォルトではエラーが発生すると停止します。ロールバックしたトランザクションの挿入行はコミットされませんが、それ以前に別途コミットしたバッチは残ります。10回のリクエストが成功し、11回目が失敗したスクリプトでは、結果は部分的に反映されています。最後のエラーだけを根拠に、ファイル全体を最初からやり直してはいけません。

制約とトリガーもレビュー対象に含めます。外部キーに必要なのは、型が正しい数値だけではなく、取り込み先に存在する参照先です。トリガーは行を拒否または変更したり、別の処理を開始したりすることがあります。ファイルが拒否されたときの常套手段として、整合性チェックを無効にしてはいけません。入力側と取り込み先でIDが異なる場合は、外部キーを伴うインポートのガイドを参照してください。

大きなファイルでは、実態に近い事前検証で、実行時間、ディスク使用量、WALの増加量、ロック、アプリケーションのレイテンシーを測定します。その結果に基づいて、サイズを制限したバッチやメンテナンス時間帯を選びます。ダッシュボードのファイルサイズ上限は、ほかの取り込み方法の性能を保証するものではありません。

オンボーディング完了前に結果を検証する

解析した入力レコードを数え、承認済みの除外を記録し、受け入れることになった集合を取り込み先と比較します。連絡先を200件受け入れたなら、挿入行が200行であることは有用な証拠です。それでも、別の200件を取り込んでいる可能性や、正しい連絡先を誤ったテナントに割り当てている可能性は残ります。

安定した業務キーを比較し、重要な変換済みフィールドを確認し、通常のアプリケーションの読み取り経路でも動作を確かめます。認可されたテナント内で、信頼できるインポートの帰属情報、またはレビュー済みの入力IDと取り込み先IDの対応表を使い、今回のインポートに属する行を特定してください。テナントで絞り込むだけでは、既存の行も含まれます。帰属情報を利用できない場合は、インポート後の全体について明示した期待値と比較し、その限界を記載します。

インポート後の検証ガイドには、キーの欠落や値の不一致を調べる、実行可能な例があります。承認済みの入力データ、マッピング、結果は、合意した保持方針に従ってまとめて保存してください。これらの記録があれば、失敗した処理や顧客からの修正依頼をはるかに解決しやすくなります。

出典と関連資料