如何通过Streamlit file_uploader将文件上传至Snowflake Stage?
Streamlit上传文件到Snowflake Stage 问题解答
核心疑问:是否需要tempfile?
Streamlit的UploadedFile是内存中的类文件对象(继承自BytesIO),并非磁盘上的实际文件。而Snowflake的file.put()方法需要接收本地磁盘文件路径作为参数,因此无法直接传入UploadedFile。使用tempfile是可靠的解决方案——把内存中的文件内容落地成临时磁盘文件,再传给Snowflake接口。
UploadedFile工作原理补充
st.file_uploader返回的UploadedFile对象封装了用户上传文件的字节内容,你可以通过getvalue()获取原始字节、read()读取内容,或直接按类文件对象操作,但它不会自动保存到磁盘,因此无法被依赖本地文件路径的工具直接调用。
方案1:原样上传原始文件(无需解析YAML)
如果不需要修改文件内容,直接上传原始文件即可,流程更高效:
import tempfile import os import streamlit as st uploaded_file = st.file_uploader( label="上传你的语义模型(YAML)文件", accept_multiple_files=False, type=["yaml"], ) if uploaded_file: # 创建临时文件,保留原始文件名后缀方便识别 temp_file_path = tempfile.mktemp(suffix=f"_{uploaded_file.name}") # 将上传文件的字节内容写入临时文件 with open(temp_file_path, 'wb') as temp_file: temp_file.write(uploaded_file.getvalue()) try: # 上传到Snowflake Stage st.session_state.session.file.put( local_file_name=temp_file_path, stage_location="@STAGE", auto_compress=False, overwrite=True ) st.success(f"文件 {uploaded_file.name} 已成功上传到Snowflake Stage!") finally: # 上传完成后删除临时文件,避免磁盘占用 os.unlink(temp_file_path)
方案2:解析YAML后再上传(适用于需要修改内容的场景)
如果需要先解析YAML内容、修改后再上传,可使用如下代码:
import yaml import tempfile import os import streamlit as st uploaded_file = st.file_uploader( label="上传你的语义模型(YAML)文件", accept_multiple_files=False, type=["yaml"], ) if uploaded_file: # 读取并解析YAML内容 yaml_content = uploaded_file.getvalue().decode("utf-8") yaml_data = yaml.safe_load(yaml_content) # 创建临时文件,自定义命名规则 with tempfile.NamedTemporaryFile( delete=False, mode='w', encoding='utf-8', prefix='SEMANTIC_MODEL_', suffix='.yaml' ) as temp_file: # 将修改后的YAML数据写入临时文件 yaml.dump(yaml_data, temp_file, default_flow_style=False, allow_unicode=True) temp_file_path = temp_file.name try: st.session_state.session.file.put( local_file_name=temp_file_path, stage_location="@STAGE", auto_compress=False, overwrite=True ) st.success("文件已成功上传到Snowflake Stage!") finally: os.unlink(temp_file_path)
关键注意事项
- 临时文件使用完成后务必删除,避免服务器磁盘被大量残留文件占用
- 若需要在Snowflake Stage中保留原始文件名,可通过
uploaded_file.name给临时文件命名 - 直接写入字节内容的方式比解析后再dump的性能更高,优先用于无需修改文件的场景
内容的提问来源于stack exchange,提问作者trey hannam
相关产品推荐
相关产品推荐

