[新機能]生成AIを用いたDescription生成ができるストアドプロシージャ「AI_GENERATE_TABLE_DESC」がパブリックプレビュー!TRANSLATE関数で日本語に翻訳してDescriptionを登録できるようにしてみた

[新機能]生成AIを用いたDescription生成ができるストアドプロシージャ「AI_GENERATE_TABLE_DESC」がパブリックプレビュー!TRANSLATE関数で日本語に翻訳してDescriptionを登録できるようにしてみた

2025.08.15

さがらです。

Snowflakeの新機能として、生成AIを用いたDescription生成がSQLコマンド経由で可能となるストアドプロシージャAI_GENERATE_TABLE_DESCがパブリックプレビューとなりました。

https://docs.snowflake.com/en/release-notes/2025/other/2025-08-11-sql-object-descriptions

https://docs.snowflake.com/en/user-guide/sql-cortex-descriptions

早速試してみたので、その内容についてまとめてみます。

シンプルにストアドプロシージャを実行

まず、今回リリースされたストアドプロシージャAI_GENERATE_TABLE_DESCをシンプルに試してみます。

テーブルに対するDescription生成

テーブル名を引数に入れてCALLするだけです。

CALL AI_GENERATE_TABLE_DESC( 'raw.stripe.payment');
{
  "TABLE": [
    {
      "database_name": "raw",
      "description": "The table contains records of payment transactions. Each record represents a single payment and includes details about the payment method, status, and amount.",
      "name": "payment",
      "schema_name": "stripe"
    }
  ]
}

カラムに対するDescription生成

以下のようにオプションを指定し、CALLすればOKです。ポイントとしては、use_table_dataを切り替えることでテーブルデータをスキャンしてDescriptionを生成するかどうかを選ぶことが出来ます。

以下にテーブルデータのスキャンの有無で比較した結果を載せますが、テーブルデータのスキャン有の方がより具体的な説明となっていますね!

  • テーブルデータのスキャンなし
CALL AI_GENERATE_TABLE_DESC(
  'raw.stripe.payment',
  {
    'describe_columns': true,
    'use_table_data': false
  });
{
  "COLUMNS": [
    {
      "database_name": "raw",
      "description": "The amount of the payment.",
      "name": "AMOUNT",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "The date and time when the payment was created.",
      "name": "CREATED",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "A unique identifier for each payment.",
      "name": "ID",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "A unique identifier for each order.",
      "name": "ORDERID",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "Payment method.",
      "name": "PAYMENTMETHOD",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "The status of the payment.",
      "name": "STATUS",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "The timestamp when the payment was batched.",
      "name": "_BATCHED_AT",
      "schema_name": "stripe",
      "table_name": "payment"
    }
  ],
  "TABLE": [
    {
      "database_name": "raw",
      "description": "The table contains records of payment transactions. Each record represents a single payment and includes details about the payment method, status, and amount.",
      "name": "payment",
      "schema_name": "stripe"
    }
  ]
}
  • テーブルデータのスキャンあり
CALL AI_GENERATE_TABLE_DESC(
  'raw.stripe.payment',
  {
    'describe_columns': true,
    'use_table_data': true
  });
{
  "COLUMNS": [
    {
      "database_name": "raw",
      "description": "The amount of a payment.",
      "name": "AMOUNT",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "The date on which the payment was created.",
      "name": "CREATED",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "A unique identifier.",
      "name": "ID",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "A unique identifier for each payment order.",
      "name": "ORDERID",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "The method used to make a payment.",
      "name": "PAYMENTMETHOD",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "The status of the payment.",
      "name": "STATUS",
      "schema_name": "stripe",
      "table_name": "payment"
    },
    {
      "database_name": "raw",
      "description": "The timestamp when the payment was processed.",
      "name": "_BATCHED_AT",
      "schema_name": "stripe",
      "table_name": "payment"
    }
  ],
  "TABLE": [
    {
      "database_name": "raw",
      "description": "The table contains records of payment transactions. Each record represents a single payment and includes details about the payment method, status, and amount.",
      "name": "payment",
      "schema_name": "stripe"
    }
  ]
}

TRANSLATE関数を用いて日本語のDescriptionに変換して自動で登録してくれるストアドプロシージャを考えてみた

先ほどストアドプロシージャをシンプルに実行した結果からわかる通り、英語でDescriptionが生成されてしまいます。

そのため、SnowflakeのTRANSLATE関数を用いて日本語のDescriptionに変換して自動で登録してくれるストアドプロシージャを考えてみました。(生成AIにより作成しています。)

CREATE OR REPLACE PROCEDURE DESCRIBE_TABLES_SET_COMMENT (schema_name STRING,
  set_table_comment BOOLEAN,
  set_column_comment BOOLEAN)
  RETURNS STRING
  LANGUAGE PYTHON
  RUNTIME_VERSION = '3.10'
  PACKAGES=('snowflake-snowpark-python','joblib')
  HANDLER = 'main'
AS
$$
import json
from joblib import Parallel, delayed
import multiprocessing

def translate_to_japanese(session, text):
    """英語のテキストを日本語に翻訳する関数"""
    try:
        # 英語から日本語に翻訳
        result = session.sql(f"""
            SELECT SNOWFLAKE.CORTEX.TRANSLATE('{text.replace("'", "''")}', 'en', 'ja')
        """).collect()
        return result[0][0] if result else text
    except Exception as e:
        # エラーが発生した場合は元のテキストを返す
        print(f"Translation error: {str(e)}")
        return text

def generate_descr(session, schema_name, table, set_table_comment, set_column_comment):
    table_name = table['TABLE_NAME']
    async_job = session.sql(f"CALL AI_GENERATE_TABLE_DESC( '{schema_name}.{table_name}',{{'describe_columns': true, 'use_table_data': true}})").collect_nowait()
    result = async_job.result()
    output = json.loads(result[0][0])
    columns_ret = output["COLUMNS"]
    table_ret = output["TABLE"][0]

    # テーブルの説明を取得して日本語に翻訳
    table_description = table_ret["description"]
    table_description_jp = translate_to_japanese(session, table_description)

    table_name = table_ret["name"]
    database_name = table_ret["database_name"]
    schema_name = table_ret["schema_name"]

    if (set_table_comment):
        # 日本語の説明文のシングルクォートをエスケープ
        table_description_jp = table_description_jp.replace("'", "\\'")
        session.sql(f"""ALTER TABLE {database_name}.{schema_name}.{table_name} SET COMMENT = '{table_description_jp}'""").collect()

    for column in columns_ret:
        column_description = column["description"]
        column_name = column["name"]

        if (set_column_comment):
            # カラムの説明を日本語に翻訳
            column_description_jp = translate_to_japanese(session, column_description)
            # 日本語の説明文のシングルクォートをエスケープ
            column_description_jp = column_description_jp.replace("'", "\\'")
            session.sql(f"""ALTER TABLE {database_name}.{schema_name}.{table_name} MODIFY COLUMN {column_name} COMMENT '{column_description_jp}'""").collect()

    return 'Success'

def main(session, schema_name, set_table_comment, set_column_comment):
    schema_name = schema_name.upper()
    tablenames = session.sql(f"""SELECT table_name
                      FROM information_schema.tables
                      WHERE table_schema = '{schema_name}'
                      AND table_type = 'BASE TABLE'""").collect()
    try:
        Parallel(n_jobs=multiprocessing.cpu_count(), backend="threading")(
                delayed(generate_descr)(
                    session,
                    schema_name,
                    table,
                    set_table_comment,
                    set_column_comment,
                ) for table in tablenames
            )
        return 'Success'
    except Exception as e:
        # Catch and return the error message
        return f"An error occurred: {str(e)}"
$$;

このストアドプロシージャを利用する場合は、下記のようにコマンドを実行すればOKです。注意点として、第1引数のスキーマはスキーマ名だけを入力する必要があります。(<database名>.<schema名>はNG)

CALL describe_tables_set_comment('stripe', true, true);

これを実行すると、下図のように日本語でDescriptionが登録されました!

2025-08-15_08h17_34

2025-08-15_08h16_56

最後に

Snowflakeの新機能として、生成AIを用いたDescription生成がSQLコマンド経由で可能となるストアドプロシージャAI_GENERATE_TABLE_DESCがパブリックプレビューとなりましたので、TRANSLATE関数も用いて、日本語に翻訳してDescriptionを登録できるようにしてみました。

労力がかかるDescriptionの入力について、ベースラインを整える上ではとても良いのではないでしょうか!ぜひご活用ください!

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.