🗂️

スプシのテーブル定義書を「1時間」でリポジトリ管理に移行できたよ【GAS × Claude】

に公開

こんにちは、mayaです!

先日、チームのテーブル定義書をGoogleスプレッドシートからtbls + Git管理に移行しました。

tblsというライブラリを使うことで手作業ゼロでDBスキーマをMarkdown化できることはわかってたのですが、スプレッドシートだけに記載しているテーブル説明、カラム説明などをどうやって移行しようか悩んでました。

「テーブル数十個あるけど、これ全部手動でやるの...?」と思ったりしてたんですが、
結論としては、Google Apps Script + Claude の組み合わせでほぼ手作業ゼロで移行できちゃいました!

今回は「どうやって移行するか」の具体的な手順を詳しくシェアします。

この記事で分かること

  • スプレッドシートからtbls移行時の最大の課題とは
  • Google Apps Scriptでコメント情報を一括抽出する方法
  • Claude/Clineを使ったtbls設定ファイル自動生成
  • 実際の移行手順(ステップバイステップ)
  • 移行時間を大幅短縮するコツとポイント

筆者のステータス

  • Web開発経験3年程度のエンジニア
  • Google Apps Script経験あり(基本的な操作レベル)
  • Claude/Cline愛用者🙋‍♂️

移行の最大の課題:コメント情報の移管問題

tblsを使えばデータベースのスキーマ構造(テーブル名、カラム名、データ型など)は自動で取得できます。
しかし、スプレッドシートに蓄積されたコメント情報は別途移行が必要でした。

移行が必要だったコメント情報

私たちのスプレッドシートには、以下のような情報が大量に蓄積されていました:

テーブルレベルのコメント

  • 「このテーブルの運用上の注意点」
  • 「他システムとの連携仕様」
  • 「過去の変更履歴と背景」

カラムレベルのコメント

  • 「このフィールドの業務的な意味」
  • 「設定可能な値の範囲と制約」
  • 「他テーブルとの関連性」

これらの情報は単なる技術仕様ではなく、チームが長年蓄積してきた業務ナレッジです。
手動で移行するとなると...

  • 対象:約30テーブル × 平均15カラム = 450箇所
  • 推定作業時間:1箇所あたり3分 × 450箇所 = 22.5時間😭

「これは現実的じゃない...」と思ったところで、自動化を検討しました。

解決策:Google Apps Script でコメント情報を一括抽出

スプレッドシートの構造分析

まず、移行対象のスプレッドシートの構造を分析しました。

私たちの場合、以下のような構造でした:

【テーブル定義書】スプレッドシート
├── usersテーブル(シート)
│   ├── A列:カラム名
│   ├── B列:データ型
│   ├── C列:NOT NULL
│   ├── D列:デフォルト値
│   └── E列:コメント ← これを抽出したい!
├── productsテーブル(シート)
└── ordersテーブル(シート)

各シートの1行目にはテーブル全体のコメントが記載されており、
E列の各セルにはカラムごとのコメントが入っている状態でした。

GASスクリプトの作成

Google Apps Scriptで、全シートのコメント情報を一括抽出するスクリプトを作成しました。

extractComments.gs
function extractAllTableComments() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheets = spreadsheet.getSheets();
  const result = {};
  
  sheets.forEach(sheet => {
    const sheetName = sheet.getName();
    
    // シート名がテーブル名として使用される想定
    if (sheetName.includes('設定') || sheetName.includes('メモ')) {
      return; // 設定用シートはスキップ
    }
    
    console.log(`Processing sheet: ${sheetName}`);
    
    // テーブル全体のコメント(A1セルから取得)
    const tableComment = sheet.getRange('A1').getNote() || 
                        sheet.getRange('A1').getValue();
    
    // カラムコメントの抽出
    const columnComments = {};
    const lastRow = sheet.getLastRow();
    
    // 2行目から開始(1行目はヘッダー)
    for (let row = 2; row <= lastRow; row++) {
      const columnName = sheet.getRange(row, 1).getValue(); // A列:カラム名
      const comment = sheet.getRange(row, 5).getValue();    // E列:コメント
      
      if (columnName && comment) {
        columnComments[columnName] = comment;
      }
    }
    
    result[sheetName] = {
      tableComment: tableComment,
      columnComments: columnComments
    };
  });
  
  // 結果をJSON形式で出力
  console.log('=== 抽出結果 ===');
  console.log(JSON.stringify(result, null, 2));
  
  return result;
}

// 実行用の関数
function main() {
  extractAllTableComments();
}

実行結果

このスクリプトを実行すると、以下のようなJSON形式でコメント情報が抽出されました:

{
  "users": {
    "tableComment": "会員登録したユーザーの基本情報を管理するテーブル。ECサイトでの購入履歴や配送先情報と紐付けされる。",
    "columnComments": {
      "id": "ユーザーの一意識別子",
      "email": "ログイン時に使用するメールアドレス",
      "display_name": "サイト上で表示される名前。商品レビュー等で公開される",
      "created_at": "アカウント作成日時",
      "updated_at": "最終更新日時"
    }
  },
  "products": {
    "tableComment": "ECサイトで販売する商品情報を管理するテーブル。在庫管理や注文管理と連携する。",
    "columnComments": {
      "id": "商品の一意識別子",
      "product_code": "商品管理用の一意コード。JANコードとは別管理",
      "name": "商品名",
      "price": "税抜き価格(円)",
      "status": "0:非公開 1:公開中 2:売り切れ"
    }
  }
}

この時点で約10分で全コメント情報の抽出が完了しました!

Claude/Clineを使った自動変換プロセス

抽出したJSON形式のコメント情報を、tblsの設定ファイル(tbls.yml)形式に変換する必要がありました。

Claude への変換依頼

抽出したJSONデータをClaudeに渡して、以下のプロンプトで変換をお願いしました:

以下のJSON形式のコメント情報を、tblsのtbls.ymlファイルのcomments形式に変換してください。

【抽出したJSONデータ】
{抽出結果をペースト}

【変換後の形式】
```yaml
comments:
  -
    table: テーブル名
    tableComment: |
      テーブルコメント
    columnComments:
      カラム名: カラムコメント

以下の点に注意して変換してください:

  • 複数行のコメントは | (パイプ) を使用
  • 特殊文字のエスケープに注意
  • YAML形式として正しく動作する形に整形

### Claude の変換結果

Claudeは約30秒で、以下のような完璧なtbls.yml形式に変換してくれました:

```yaml:tbls.yml(変換結果)
comments:
  -
    table: users
    tableComment: |
      会員登録したユーザーの基本情報を管理するテーブル。
      ECサイトでの購入履歴や配送先情報と紐付けされる。
    columnComments:
      id: ユーザーの一意識別子
      email: ログイン時に使用するメールアドレス
      display_name: |
        サイト上で表示される名前。
        商品レビュー等で公開される
      created_at: アカウント作成日時
      updated_at: 最終更新日時
  -
    table: products
    tableComment: |
      ECサイトで販売する商品情報を管理するテーブル。
      在庫管理や注文管理と連携する。
    columnComments:
      id: 商品の一意識別子
      product_code: |
        商品管理用の一意コード。
        JANコードとは別管理
      name: 商品名
      price: 税抜き価格(円)
      status: |
        0: 非公開
        1: 公開中
        2: 売り切れ

この変換作業も約5分で完了しました!

実際の移行手順(ステップバイステップ)

では、実際に私が行った移行手順を詳しく説明します。

Step 1: 事前準備(約30分)

1-1. スプレッドシートの整理

  • シート名をテーブル名と完全一致させる
  • 不要なシート(メモ、設定など)を識別
  • カラム配置の統一確認

1-2. tblsの基本設定

tbls.yml
dsn: mysql://username:password@localhost:3306/ec_shop
docPath: docs/db/schema

Step 2: GASでコメント抽出(約1分)

2-1. スクリプト作成と実行

// 上記のextractComments.gsを使用
function main() {
  const result = extractAllTableComments();
  
  // 結果をスプレッドシートに出力(コピペしやすくするため)
  const outputSheet = SpreadsheetApp.getActiveSpreadsheet()
    .insertSheet('抽出結果');
  
  outputSheet.getRange(1, 1).setValue(JSON.stringify(result, null, 2));
}

2-2. 結果の確認と調整

  • 不正なデータの除去
  • 特殊文字の事前チェック

Step 3: Claude での変換(約5分)

3-1. 変換実行

  • 抽出したJSONをClaude/Clineに投げる
  • 上記のプロンプトで変換依頼

3-2. 結果の検証

  • YAML形式として正しいかチェック
  • 特殊文字のエスケープ確認

Step 4: tbls設定への反映(約5分)

4-1. tbls.ymlの更新
反映作業もClaudeに丸投げするのがおすすめです

tbls.yml
dsn: mysql://username:password@localhost:3306/ec_shop
docPath: docs/db/schema

# Claudeで変換した内容をここに追加
comments:
  - 
    table: users
    # ... 変換結果を出力

4-2. 動作確認

# ドキュメント生成テスト
tbls doc --force

# 生成結果の確認
ls docs/db/schema/
cat docs/db/schema/users.md

Step 5: 最終チェックと運用開始(約15分)

5-1. 全テーブルの確認

  • 各テーブルのマークダウンファイルを確認
  • コメントが正しく反映されているかチェック

5-2. チームメンバーへの共有

  • 移行完了の報告
  • 新しい運用方法の説明

移行時間短縮のコツとポイント

今回の移行で学んだ、時間短縮のポイントをシェアします。

事前準備で8割決まる

1. スプレッドシートの命名規則統一

  • シート名 = テーブル名にしておく
  • カラム配置を統一(A列:カラム名、E列:コメントなど)

2. 不要データの事前除去

  • 設定用シート、メモ用シートを別途管理
  • 空行・空セルの整理

バッチ処理での効率化

3. GASでの一括処理

// テーブルごとではなく、全テーブル一括で処理
const allTables = extractAllTableComments();

// エラーハンドリングを含めた堅牢なスクリプト
sheets.forEach(sheet => {
  try {
    // 処理
  } catch (error) {
    console.error(`Error in sheet ${sheet.getName()}:`, error);
  }
});

4. Claude での効率的なプロンプト設計

【効果的だったプロンプト】
- 明確な入力形式の指定
- 期待する出力形式の例示
- エラーケースへの対応指示

【避けるべきプロンプト】
- 曖昧な指示
- 一度に複数のタスクを混在

検証プロセスの自動化

5. YAML形式チェック

# YAMLファイルの構文チェック
python -c "import yaml; yaml.safe_load(open('tbls.yml'))"

6. tbls での動作確認

# ドライラン的な実行
tbls doc --config tbls.yml --dry-run

実際の移行にかかった時間

従来の手動移行(予想)

  • 22.5時間(450箇所 × 3分)

今回の自動化移行(実績)

  • 事前準備:30分
  • GAS作成・実行:5分
  • Claude変換:5分
  • 設定反映:5分
  • 最終確認:15分
  • 合計:1時間 🎉

時間短縮率:95.5%

移行後の感想とメリット

想定以上に良かった点

1. 情報の欠損がゼロ
手動移行だと確実に「コピペし忘れ」や「微妙なニュアンスの変更」が起こりそうでしたが、自動化により完全に移行できました。

2. 移行作業自体が楽しかった
「面倒な作業」から「技術的なチャレンジ」に変わったおかげで、むしろ楽しく進められました!

3. 再現可能なプロセス
今回作ったGASスクリプトは、他のプロジェクトでも使い回せそうです。

注意すべきポイント

1. スプレッドシートの構造依存

  • シートの構造が統一されていることが前提
  • レイアウトが大きく異なる場合はスクリプトの調整が必要

2. データの品質

  • 元データの品質がそのまま移行されるため、事前クリーニングが重要
  • 特殊文字や改行コードの扱いに注意

今後の展開予定

他プロジェクトへの適用

今回のノウハウを社内に共有し、(僕が関わってる以外の)他プロジェクトでも同様の移行が進めば良いな〜と期待してます。
弊社のプロジェクトは、だいたいGoogleスプレッドシートでテーブル定義書を管理してるので、この方法をまんま使えるはず...!

AIエージェントとの連携

現在僕が所属するプロジェクトでは、AIコーディングエージェントが作業しやすい環境を整えるために、実装ガイドラインや機能仕様書など、あらゆるドキュメントをリポジトリ管理に移行しています。

今回のテーブル定義書移管もその一環でして、AIエージェントがプロジェクトを理解する一助になれば良いなと期待しているところです。


Google Apps Script + Claude の組み合わせで、想定していた数日の作業が1時間半で完了しました!
手作業だったら確実に途中で挫折していたと思います😅

この方法なら「移行が面倒だから...」という理由でGit管理への移行を躊躇している方も、
気軽にチャレンジできるのではないでしょうか。

最後まで読んでいただき、ありがとうございました!
同じような移行作業で困っている方の参考になれば嬉しいです🙋‍♂️

Discussion