Streamlit代码报错SnowparkPandasException:无法写入DataFrame至指定表
我需要创建一个供应商评分表单,支持1-10分评分、添加自由文本评论,并将结果保存到RESULTAT_SUPPLIERS表中。该表与我使用的SFC_SAMPLES.TPCH_SF1架构不在同一位置。
执行Streamlit代码时出现以下报错:
SnowparkPandasException: (1114): Cannot write pandas DataFrame to table "M_HENRY_DB.PUBLIC.RESULTAT_SUPPLIERS" because it does not exist. Create table before trying to write a pandas DataFrame
但我确认该表已存在,请求协助排查原因。
附完整代码:
# Import libraries from snowflake.snowpark.context import get_active_session from snowflake.snowpark.functions import sum, col, to_date, year import calendar import altair as alt import streamlit as st import pandas as pd import snowflake.snowpark as snowpark # Set page config st.set_page_config(layout="wide") # Get current session session = get_active_session() def load_data(): # Load Supplier data snow_df_supplier = session.table("SFC_SAMPLES.TPCH_SF1.SUPPLIER") # Load Line Item data snow_df_lineitem = session.table("SFC_SAMPLES.TPCH_SF1.LINEITEM") return snow_df_supplier, snow_df_lineitem # Load and cache data snow_df_supplier, snow_df_lineitem = load_data() # Sidebar - Supplier filter st.sidebar.header('Supplier Filter') selected_supplier = st.sidebar.selectbox('Select Supplier:', snow_df_supplier.select('S_NAME').distinct().collect()) filtered_supplier_df = snow_df_supplier.filter(col('S_NAME') == selected_supplier) # Display supplier information st.header(f"Supplier Information - {selected_supplier}") st.table(filtered_supplier_df.select('S_NAME', 'S_ADDRESS','S_NATIONKEY','S_PHONE').to_pandas()) # Display revenue year over year with a bar chart for the selected supplier(s) st.header(f"Revenue Year Over Year for Selected Supplier") # Format the L_COMMITDATE to 'YYYY-MM-DD' snow_df_lineitem = snow_df_lineitem.withColumn('L_COMMITDATE', to_date(snow_df_lineitem['L_COMMITDATE'])) # Filter data for the selected supplier filtered_lineitem_df = snow_df_lineitem.filter(col('L_SUPPKEY') == filtered_supplier_df.select('S_SUPPKEY').collect()[0]['S_SUPPKEY']) # Extract the year from L_COMMITDATE filtered_lineitem_df = filtered_lineitem_df.withColumn('Year', year('L_COMMITDATE')) # Calculate revenue by grouping by Year and summing L_EXTENDEDPRICE revenue_df = filtered_lineitem_df.groupBy('Year').agg(sum('L_EXTENDEDPRICE').alias('REVENUE')).toPandas() st.write(revenue_df) # Display Altair bar chart chart = alt.Chart(revenue_df).mark_bar().encode( x='Year:O', y='REVENUE', tooltip=['Year:O', 'REVENUE'] ).properties(width=800, height=400) st.altair_chart(chart, use_container_width=True) # Streamlit config st.header("Supplier Grading Form") # Get supplier name from the user selected_supplier = st.text_input('Supplier Name:') # Get grade and comment from the user grade = st.slider('Grade (1 to 10):', min_value=1, max_value=10, step=1) comment = st.text_area('Free Text Comment:') submit_button = st.button('❄️ Submit to Snowflake') # Connect to Snowflake session = snowpark.session._get_active_session() # Setup the ability to save user-entered allocations and predicted value back to Snowflake if submit_button: with st.spinner("Making snowflakes..."): # Prepare data to insert into the table data_to_insert = [(selected_supplier, grade, comment)] columns = ['Supplier', 'Grade', 'Comment'] insert_df = pd.DataFrame(data_to_insert, columns=columns) # Write data to Snowflake table session.write_pandas(insert_df, "M_HENRY_DB.PUBLIC.RESULTAT_SUPPLIERS") st.success("✅ Successfully wrote the grading to your Snowflake account!") st.snow()
权限验证:确认当前会话使用的角色拥有
M_HENRY_DB.PUBLIC.RESULTAT_SUPPLIERS表的写入权限(INSERT/UPDATE),以及该数据库、schema的USAGE权限。可执行以下SQL检查:SHOW GRANTS ON TABLE M_HENRY_DB.PUBLIC.RESULTAT_SUPPLIERS; SHOW GRANTS ON SCHEMA M_HENRY_DB.PUBLIC; SHOW GRANTS ON DATABASE M_HENRY_DB;大小写与引号问题:如果表是带双引号创建的(比如混合/小写名称),未加引号的全限定名会被Snowflake转为大写,导致匹配失败。可尝试带引号的写法:
session.write_pandas(insert_df, "\"M_HENRY_DB\".\"PUBLIC\".\"RESULTAT_SUPPLIERS\"")会话上下文切换:显式切换到目标数据库和schema后再写入,避免上下文默认值干扰:
session.use_database("M_HENRY_DB") session.use_schema("PUBLIC") session.write_pandas(insert_df, "RESULTAT_SUPPLIERS")表结构匹配检查:确认
RESULTAT_SUPPLIERS表的列名、数据类型与插入的DataFrame完全一致。比如DataFrame的Supplier(字符串)、Grade(整数)、Comment(字符串)需与表列一一对应。可执行SQL查看表结构:DESCRIBE TABLE M_HENRY_DB.PUBLIC.RESULTAT_SUPPLIERS;关闭自动创建表逻辑:
write_pandas默认会尝试创建表,即使表已存在。显式关闭该参数,避免自动创建逻辑引发的判断错误:session.write_pandas( insert_df, "M_HENRY_DB.PUBLIC.RESULTAT_SUPPLIERS", auto_create_table=False )
内容的提问来源于stack exchange,提问作者Snowflake Novice

