如何通过Streamlit将GeoTIFF/Shapefile上传至Snowflake数据库?
上传GeoTIFF/Shapefile到Snowflake(Streamlit集成方案)
一、前置准备
首先确认Snowflake环境满足以下条件:
- 账户已启用地理空间功能(默认开启,若未启用需联系管理员)
- 操作角色拥有
CREATE STAGE、PUT、COPY INTO等权限 - 创建对应的数据表或临时阶段用于存储/解析空间文件
二、GeoTIFF文件上传与处理
1. Streamlit端获取文件
通过st.file_uploader指定文件类型,读取二进制内容:
import streamlit as st import snowflake.connector # 复用已有的Snowflake连接逻辑 conn = snowflake.connector.connect( user=st.secrets["snowflake"]["user"], password=st.secrets["snowflake"]["password"], account=st.secrets["snowflake"]["account"], warehouse=st.secrets["snowflake"]["warehouse"], database=st.secrets["snowflake"]["database"], schema=st.secrets["snowflake"]["schema"] ) # 上传GeoTIFF uploaded_tiff = st.file_uploader("上传GeoTIFF文件", type=["tif", "tiff"]) if uploaded_tiff is not None: tiff_content = uploaded_tiff.read()
2. Snowflake端存储/解析
方式1:直接存储二进制文件
先创建存储表:
CREATE TABLE GEO_TIFF_STORAGE ( FILE_NAME VARCHAR(255), UPLOAD_TIME TIMESTAMP DEFAULT CURRENT_TIMESTAMP(), TIFF_BINARY BINARY );
再在Streamlit中执行插入:
cur = conn.cursor() try: insert_sql = "INSERT INTO GEO_TIFF_STORAGE (FILE_NAME, TIFF_BINARY) VALUES (%s, %s)" cur.execute(insert_sql, (uploaded_tiff.name, tiff_content)) conn.commit() st.success("GeoTIFF文件上传完成") finally: cur.close()
方式2:解析为地理空间对象
利用Snowflake的ST_FROM_GEOTIFF函数直接解析文件中的空间数据,需先上传到临时阶段:
cur = conn.cursor() try: # 创建临时阶段 cur.execute("CREATE OR REPLACE TEMP STAGE TIFF_STAGE") # 上传文件到阶段(内部处理二进制流) cur.execute(f"PUT file://{uploaded_tiff.name} @TIFF_STAGE AUTO_COMPRESS=FALSE", _internal_stage=True) # 解析并插入空间表 cur.execute(f""" INSERT INTO GEO_SPATIAL_DATA (FILE_NAME, GEOMETRY) SELECT '{uploaded_tiff.name}', ST_FROM_GEOTIFF(@TIFF_STAGE/{uploaded_tiff.name}) """) conn.commit() st.success("GeoTIFF解析并存储成功") finally: cur.close()
三、Shapefile文件上传与处理
Shapefile是多文件集合(.shp、.shx、.dbf等),必须上传完整ZIP压缩包:
1. Streamlit端获取ZIP包
import tempfile import os uploaded_shp_zip = st.file_uploader("上传Shapefile压缩包(ZIP格式)", type=["zip"]) if uploaded_shp_zip is not None: # 写入临时文件供Snowflake调用 with tempfile.NamedTemporaryFile(delete=False, suffix=".zip") as tmp_file: tmp_file.write(uploaded_shp_zip.read()) tmp_zip_path = tmp_file.name
2. Snowflake端解析存储
使用ST_GEOGRAPHYFROMSHAPEFILE函数解析ZIP中的Shapefile:
cur = conn.cursor() try: cur.execute("CREATE OR REPLACE TEMP STAGE SHP_STAGE") # 上传临时ZIP到阶段 cur.execute(f"PUT file://{tmp_zip_path} @SHP_STAGE AUTO_COMPRESS=FALSE") # 解析并生成数据表(按需调整属性列) cur.execute(f""" CREATE OR REPLACE TABLE SHP_SPATIAL_DATA AS SELECT t.$1::VARCHAR AS FEATURE_NAME, ST_GEOGRAPHYFROMSHAPEFILE(t.$2) AS GEOMETRY FROM @SHP_STAGE/{uploaded_shp_zip.name} (FILE_FORMAT => (TYPE = 'CSV', FIELD_OPTIONALLY_ENCLOSED_BY = '"')) t """) conn.commit() st.success("Shapefile解析并存储成功") finally: cur.close() # 清理临时文件 os.unlink(tmp_zip_path)
四、关键注意事项
- 大文件建议使用外部阶段(如S3)配合Snowflake,避免Streamlit内存溢出
- Shapefile的ZIP包必须包含所有附属文件,缺少.shx/.dbf会导致解析失败
- 可通过
ST_ASWKT/ST_ASGEOJSON函数将空间对象转换为可读格式查询
内容的提问来源于stack exchange,提问作者zaiba iqbal
相关产品推荐
相关产品推荐

