Snowflake (SiS) の Streamlit を使用してユーザーごとにパーソナライズ
導入
2024 年 7 月末に、Current_User および Row Access Policy が Snowflake の Streamlit で利用可能になりました。
このアップデートの興味深い点は、アプリケーションに接続している Snowflake ユーザーを簡単かつ安全に識別し、各ユーザーの処理をカスタマイズできることです。
カスタム ログイン メカニズムやユーザー管理テーブルをセットアップする必要がなく、次のような方法でユーザーごとに 1 つのアプリケーションをパーソナライズできます。
- ユーザーごとにアプリの表示を変更する
- ユーザーごとにパーソナライズされた分析ダッシュボードを準備する
- 行アクセス ポリシーを使用してユーザーごとに異なるクエリ出力結果を取得する (Enterprise Edition 以降)
この投稿では、個々のユーザー情報を表示するシンプルな ToDo リストを作成します。
注: この投稿は私の個人的な見解を表すものであり、Snowflake の見解ではありません。
機能の概要
目標
- 単一の共有アプリを使用して個人の ToDo リストを管理
- 行アクセス ポリシーを使用して、他の人の ToDo が表示されないようにします
完成イメージ
ユーザー TKANO の画面
ユーザーTAROの画面
前提条件
- スノーフレークアカウント
- 行アクセス ポリシーを使用するには Enterprise Edition アカウントが必要です
注記
- Snowflake の Streamlit は所有者権限で実行されるため、Current_Role は Snowflake の Streamlit アプリケーション ロールと同じになります。 (そのため、パーソナライズには使用できません)
手順
ToDoリストを保存するテーブルを作成する
ワークシートから次のコマンドを実行します:
-- Create ToDo list table CREATE TABLE IF NOT EXISTS todo_list ( id INT AUTOINCREMENT, task VARCHAR(255), status VARCHAR(20), due_date DATE, completed_date DATE, owner VARCHAR(50) );
行アクセスポリシーを作成する
このポリシーは、todo_list テーブルの所有者が Snowflake アプリケーションの Streamlit に接続されている current_user と一致する行を返します。
ワークシートから次のコマンドを実行します:
-- Create row access policy CREATE ROW ACCESS POLICY IF NOT EXISTS todo_row_access_policy AS (owner VARCHAR) RETURNS BOOLEAN -> owner = CURRENT_USER();
行アクセスポリシーを適用する
ワークシートから次のコマンドを実行します:
-- Apply row access policy ALTER TABLE todo_list ADD ROW ACCESS POLICY todo_row_access_policy ON (owner);
これでワークシートの操作は完了です。
Snowflake アプリで Streamlit を実行する
Snowflake アプリで新しい Streamlit を作成し、次のコードをコピーして貼り付けます:
行 14 は、アプリに接続している現在のユーザーを文字列として取得する場所です。
import streamlit as st from snowflake.snowpark.context import get_active_session import pandas as pd # Layout settings st.set_page_config( layout="wide" ) # Get Snowflake session session = get_active_session() # Get current user current_user = session.sql("SELECT CURRENT_USER()").collect()[0][0] # Get ToDo list def get_todo_list(): return session.table("todo_list").to_pandas() # Add or update task def upsert_task(task_id, task, status, due_date, completed_date): due_date_sql = f"'{due_date}'" if due_date else "NULL" completed_date_sql = f"'{completed_date}'" if completed_date else "NULL" if task_id: session.sql(f""" UPDATE todo_list SET task = '{task}', status = '{status}', due_date = {due_date_sql}, completed_date = {completed_date_sql} WHERE id = {task_id} """).collect() else: session.sql(f""" INSERT INTO todo_list (task, status, owner, due_date, completed_date) VALUES ('{task}', '{status}', '{current_user}', {due_date_sql}, {completed_date_sql}) """).collect() # Delete task def delete_task(task_id): session.sql(f"DELETE FROM todo_list WHERE id = {task_id}").collect() # Main function def main(): st.title(f"{current_user}'s Personal Dashboard") # Task list st.subheader(f"{current_user}'s ToDo List") todo_df = get_todo_list() # Display header col1, col2, col3, col4, col5 = st.columns([3, 2, 2, 2, 2]) col1.write("Task") col2.write("Status") col3.write("Due Date") col4.write("Completed Date") col5.write("Delete") # Display task list for _, row in todo_df.iterrows(): col1, col2, col3, col4, col5 = st.columns([3, 2, 2, 2, 2]) with col1: task = st.text_input("task", value=row['TASK'], key=f"task_{row['ID']}", label_visibility="collapsed") with col2: status = st.selectbox("status", ["Pending", "In Progress", "Completed"], index=["Pending", "In Progress", "Completed"].index(row['STATUS']), key=f"status_{row['ID']}", label_visibility="collapsed") with col3: due_date = st.date_input("due_date", value=pd.to_datetime(row['DUE_DATE']).date() if pd.notna(row['DUE_DATE']) else None, key=f"due_date_{row['ID']}", label_visibility="collapsed") with col4: completed_date = st.date_input("comp_date", value=pd.to_datetime(row['COMPLETED_DATE']).date() if pd.notna(row['COMPLETED_DATE']) else None, key=f"completed_date_{row['ID']}", label_visibility="collapsed") with col5: if st.button("Delete", key=f"delete_{row['ID']}"): delete_task(row['ID']) st.experimental_rerun() # Update database immediately if values change if task != row['TASK'] or status != row['STATUS'] or due_date != row['DUE_DATE'] or completed_date != row['COMPLETED_DATE']: upsert_task(row['ID'], task, status, due_date, completed_date) st.experimental_rerun() # Add new task st.subheader("Add New Task") new_task = st.text_input("New Task") new_status = st.selectbox("Status", ["Pending", "In Progress", "Completed"]) new_due_date = st.date_input("Due Date") if st.button("Add"): upsert_task(None, new_task, new_status, new_due_date, None) st.success("New task added") st.experimental_rerun() # Main process if __name__ == "__main__": main()
結論
どう思いますか? Current_User と行アクセス ポリシーを組み合わせることで、簡単な手順でユーザーごとにパーソナライズされた安全なアプリケーションを作成できます。これにより、あなたのアイデアに基づいて、さらにユーザーフレンドリーなアプリケーションを作成できる可能性が広がります。
いくつかの高度なアイデアには、Snowflake の Streamlit 経由でテーブルに書き込むときに Current_User 情報を署名として追加することや、パーソナル アシスタントを作成するための Cortex LLM のコンテキストとしてパーソナライズされた情報を使用することが含まれます。
Current_User の興味深い使い方にぜひ挑戦してみてください!
お知らせ
X の Snowflake の新機能アップデート
X に関する Snowflake の新着情報を共有しています。ご興味がございましたら、お気軽にフォローしてください。
英語版
Snowflake 新着情報ボット (英語版)
https://x.com/snow_new_ja
日本語版
Snowflake 新着情報ボット (日本語版)
https://x.com/snow_new_jp
変更履歴
(20240914) 最初の投稿
日本語オリジナル記事
https://zenn.dev/tsubasa_tech/articles/a23029dfe97c46
以上がSnowflake (SiS) の Streamlit を使用してユーザーごとにパーソナライズの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undress AI Tool
脱衣画像を無料で

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック

Pythonオブジェクト指向プログラミングのコアコンセプトであるPythonは、「1つのインターフェイス、複数の実装」を指し、異なるタイプのオブジェクトの統一処理を可能にします。 1。多型は、メソッドの書き換えを通じて実装されます。サブクラスは、親クラスの方法を再定義できます。たとえば、Animal ClassのSOCK()方法は、犬と猫のサブクラスに異なる実装を持っています。 2.多型の実用的な用途には、グラフィカルドローイングプログラムでdraw()メソッドを均一に呼び出すなど、コード構造を簡素化し、スケーラビリティを向上させる、ゲーム開発における異なる文字の共通の動作の処理などが含まれます。 3. Pythonの実装多型を満たす必要があります:親クラスはメソッドを定義し、子クラスはメソッドを上書きしますが、同じ親クラスの継承は必要ありません。オブジェクトが同じ方法を実装する限り、これは「アヒル型」と呼ばれます。 4.注意すべきことには、メンテナンスが含まれます

パラメーターは関数を定義するときはプレースホルダーであり、引数は呼び出し時に特定の値が渡されます。 1。位置パラメーターを順番に渡す必要があり、順序が正しくない場合は結果のエラーにつながります。 2。キーワードパラメーターはパラメーター名で指定されており、順序を変更して読みやすさを向上させることができます。 3.デフォルトのパラメーター値は、複製コードを避けるために定義されたときに割り当てられますが、変数オブジェクトはデフォルト値として避ける必要があります。 4. Argsおよび *Kwargsは、不確実な数のパラメーターを処理でき、一般的なインターフェイスまたはデコレータに適していますが、読みやすさを維持するためには注意して使用する必要があります。

イテレータは、__iter __()および__next __()メソッドを実装するオブジェクトです。ジェネレーターは、単純化されたバージョンのイテレーターです。これは、収量キーワードを介してこれらのメソッドを自動的に実装しています。 1. Iteratorは、次の()を呼び出すたびに要素を返し、要素がなくなると停止例外をスローします。 2。ジェネレーターは関数定義を使用して、オンデマンドでデータを生成し、メモリを保存し、無限シーケンスをサポートします。 3。既存のセットを処理するときに反復器を使用すると、大きなファイルを読み取るときに行ごとにロードするなど、ビッグデータや怠zyな評価を動的に生成するときにジェネレーターを使用します。注:リストなどの反復オブジェクトは反復因子ではありません。イテレーターがその端に達した後、それらは再作成する必要があり、発電機はそれを一度しか通過できません。

クラスメソッドは、@ClassMethodデコレーターを介してPythonで定義されるメソッドです。最初のパラメーターはクラス自体(CLS)で、クラス状態へのアクセスまたは変更に使用されます。特定のインスタンスではなく、クラス全体に影響を与えるクラスまたはインスタンスを通じて呼び出すことができます。たとえば、Personクラスでは、show_count()メソッドは作成されたオブジェクトの数を数えます。クラスメソッドを定義するときは、@ClassMethodデコレータを使用して、Change_Var(new_Value)メソッドなどの最初のパラメーターCLSに名前を付けてクラス変数を変更する必要があります。クラス方法は、インスタンスメソッド(自己パラメーター)および静的メソッド(自動パラメーターなし)とは異なり、工場の方法、代替コンストラクター、およびクラス変数の管理に適しています。一般的な用途には以下が含まれます。

API認証を扱うための鍵は、認証方法を正しく理解して使用することです。 1。Apikeyは、通常、リクエストヘッダーまたはURLパラメーターに配置されている最も単純な認証方法です。 2。BasicAuthは、内部システムに適したBase64エンコード送信にユーザー名とパスワードを使用します。 3。OAUTH2は、最初にclient_idとclient_secretを介してトークンを取得し、次にリクエストヘッダーにbearertokenを持ち込む必要があります。 4。トークンの有効期限に対処するために、トークン管理クラスをカプセル化し、トークンを自動的に更新できます。要するに、文書に従って適切な方法を選択し、重要な情報を安全に保存することが重要です。

PythonのMagicMethods(またはDunder Methods)は、オブジェクトの動作を定義するために使用される特別な方法であり、二重のアンダースコアで始まり、終了します。 1.オブジェクトは、追加、比較、文字列表現などの組み込み操作に応答できるようにします。 2.一般的なユースケースには、オブジェクトの初期化と表現(__init__、__Repr__、__str__)、算術操作(__ add__、__sub__、__mul__)、および比較操作(__eq__、___lt__)が含まれます。 3。それを使用するときは、彼らの行動が期待を満たしていることを確認してください。たとえば、__Repr__はリファクタリング可能なオブジェクトの式を返す必要があり、算術メソッドは新しいインスタンスを返す必要があります。 4.過剰使用または混乱を招くことは避ける必要があります。

Pythonのごみ収集メカニズムは、参照カウントと定期的なごみ収集を通じてメモリを自動的に管理します。そのコアメソッドは参照カウントであり、オブジェクトの参照の数がゼロになるとすぐにメモリを解放します。ただし、円形の参照を処理できないため、ループを検出してクリーニングするために、Garbage Collection Module(GC)が導入されています。通常、ガベージコレクションは、プログラムの操作中に参照カウントが減少したときにトリガーされます。割り当てとリリースの差がしきい値を超える、またはgc.collect()が手動で呼ばれるときにトリガーされます。ユーザーは、gc.disable()を介して自動リサイクルをオフにし、gc.collect()を手動で実行し、gc.set_threshold()を介して制御を実現するためにしきい値を調整できます。すべてのオブジェクトがループリサイクルに参加するわけではありません。参照が含まれていないオブジェクトが参照カウントによって処理されている場合、それは組み込まれています

PythonManagesMemoryAutomatelyUsingTuntingAndagarBageCollector.ReferencountingTrackShowManyvariablesRefertoAnobject、およびThemeMoryisfreed.
