You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Snowflake上Streamlit应用获取用户仓库列表的问题求助

解决Snowflake原生Streamlit应用获取用户仓库列表的问题

问题根源

  1. 原生Streamlit应用仅支持创建/使用OWNER'S RIGHTS模式的存储过程,无法启用EXECUTE AS CALLER,存储过程执行时的会话上下文为应用所有者,而非调用用户。
  2. 原方案中LAST_QUERY_ID()依赖前序SHOW WAREHOUSES的查询上下文,但在OWNER权限模式下,两次查询的会话上下文不匹配,导致出现query_id_place_holder_XYZ not found错误。

解决方案:直接查询系统视图替代SHOW+RESULT_SCAN

放弃依赖SHOW命令和RESULT_SCAN的方式,改用Snowflake内置的INFORMATION_SCHEMA.WAREHOUSES视图获取仓库列表,该方式更稳定且符合原生应用的权限限制。

1. 修改存储过程定义(setup.sql)

CREATE OR REPLACE PROCEDURE public.get_available_warehouses()
RETURNS TABLE(
    name VARCHAR,
    type VARCHAR,
    size VARCHAR,
    state VARCHAR,
    is_default BOOLEAN,
    is_current BOOLEAN,
    auto_suspend NUMBER,
    auto_resume BOOLEAN,
    min_cluster_count NUMBER,
    max_cluster_count NUMBER,
    scaling_policy VARCHAR,
    resource_monitor VARCHAR,
    comment VARCHAR
)
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'get_available_warehouses'
OWNER'S RIGHTS
AS
$$
def get_available_warehouses(session):
    # 直接查询INFORMATION_SCHEMA获取当前账户下的仓库列表
    return session.sql("""
        SELECT 
            WAREHOUSE_NAME AS name,
            WAREHOUSE_TYPE AS type,
            WAREHOUSE_SIZE AS size,
            WAREHOUSE_STATE AS state,
            IS_DEFAULT AS is_default,
            IS_CURRENT AS is_current,
            AUTO_SUSPEND AS auto_suspend,
            AUTO_RESUME AS auto_resume,
            MIN_CLUSTER_COUNT AS min_cluster_count,
            MAX_CLUSTER_COUNT AS max_cluster_count,
            SCALING_POLICY AS scaling_policy,
            RESOURCE_MONITOR AS resource_monitor,
            COMMENT AS comment
        FROM INFORMATION_SCHEMA.WAREHOUSES
        WHERE CURRENT_ACCOUNT() = WAREHOUSE_OWNER
    """)
$$;

2. Streamlit应用调用代码

import snowflake.snowpark as snowpark
import streamlit as st

def main(session: snowpark.Session):
    # 调用存储过程并转换为Pandas DataFrame
    warehouses_df = session.sql("CALL public.get_available_warehouses()").to_pandas()
    
    # 生成下拉菜单选项
    if not warehouses_df.empty:
        warehouse_options = warehouses_df['NAME'].tolist()
        selected_warehouse = st.selectbox("选择仓库", warehouse_options)
        st.success(f"已选择仓库:{selected_warehouse}")
    else:
        st.warning("未找到可用仓库")

if __name__ == "__main__":
    session = snowpark.Session.builder.appName("WarehouseSelector").getOrCreate()
    main(session)

进阶权限过滤(可选)

如果需要返回当前用户有权限使用的仓库(而非整个账户下的所有仓库),可修改存储过程中的SQL查询为:

SELECT w.WAREHOUSE_NAME AS name
FROM INFORMATION_SCHEMA.WAREHOUSES w
JOIN INFORMATION_SCHEMA.GRANTS_TO_USERS g
    ON w.WAREHOUSE_NAME = g.GRANTEE_NAME
WHERE g.GRANTEE_NAME = CURRENT_USER()
    AND g.PRIVILEGE IN ('USAGE', 'MODIFY')
GROUP BY w.WAREHOUSE_NAME

内容的提问来源于stack exchange,提问作者Sam W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 01:25:21