如何使用Snowflake合并S3同存储桶两表并迁移至其他桶
Snowflake合并S3双表跨桶迁移操作指南(新手适用)
前置准备
先把权限配好,不然后面所有步骤都会报权限错:
- 给Snowflake授权的IAM角色配源S3桶的读权限:需要
s3:GetObject、s3:ListBucket两个权限,覆盖当前表、历史表的存放路径 - 给同一个IAM角色配目标S3桶的写权限:需要
s3:PutObject、s3:ListBucket权限,如果要覆盖目标路径已有文件再加s3:DeleteObject
优先用存储集成+IAM角色的认证方式,不要直接在阶段里写AK/SK,避免密钥泄露,新手用这种方式配置一次后续复用也方便
步骤1:创建存储集成与外部阶段
外部阶段是Snowflake对接S3的入口,先建源端和目标端的对应配置:
-- 1. 建源S3桶的存储集成 CREATE OR REPLACE STORAGE INTEGRATION source_s3_int TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'S3' ENABLED = TRUE STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::替换成你的AWS账号ID:role/替换成给Snowflake授权的IAM角色名' STORAGE_ALLOWED_LOCATIONS = ('s3://替换成你的源S3桶名/'); -- 2. 建目标S3桶的存储集成 CREATE OR REPLACE STORAGE INTEGRATION target_s3_int TYPE = EXTERNAL_STAGE STORAGE_PROVIDER = 'S3' ENABLED = TRUE STORAGE_AWS_ROLE_ARN = 'arn:aws:iam::替换成你的AWS账号ID:role/替换成给Snowflake授权的IAM角色名' STORAGE_ALLOWED_LOCATIONS = ('s3://替换成你的目标S3桶名/');
执行完上面的SQL后,跑DESC STORAGE INTEGRATION source_s3_int;和DESC STORAGE INTEGRATION target_s3_int;,拿到返回结果里的STORAGE_AWS_IAM_USER_ARN和STORAGE_AWS_EXTERNAL_ID,填到对应IAM角色的信任关系里,完成Snowflake的访问授权。
授权完成后建三个外部阶段,分别对接当前表、历史表、目标输出路径:
-- 对接当前数据存放路径的阶段 CREATE OR REPLACE STAGE source_current_stage URL = 's3://替换成源桶名/当前表的存放路径/' STORAGE_INTEGRATION = source_s3_int FILE_FORMAT = ( TYPE = 'CSV' -- 替换成你实际的文件格式,支持PARQUET/JSON/ORC等 -- 如果是CSV,按实际情况补参数,比如 SKIP_HEADER=1, FIELD_DELIMITER=',', NULL_IF=('') ); -- 对接历史数据存放路径的阶段 CREATE OR REPLACE STAGE source_history_stage URL = 's3://替换成源桶名/历史表的存放路径/' STORAGE_INTEGRATION = source_s3_int FILE_FORMAT = (和上面source_current_stage完全一致的格式配置); -- 对接目标桶输出路径的阶段 CREATE OR REPLACE STAGE target_output_stage URL = 's3://替换成目标桶名/合并后数据的存放路径/' STORAGE_INTEGRATION = target_s3_int FILE_FORMAT = (和源文件一致的格式配置);
校验小技巧:分别跑
LIST @source_current_stage;和LIST @source_history_stage;,如果能正常返回路径下的文件列表,说明权限和路径配置正确;再跑SELECT $1, $2 FROM @source_current_stage LIMIT 10;,如果能正常读出文件内容,说明文件格式配置正确,可以往下走。
步骤2:合并两张表的数据
用临时表承接数据就行,会话结束自动删除,不会产生额外存储成本:
-- 建临时表,字段名、字段顺序、数据类型要和两张源表完全对齐 CREATE OR REPLACE TEMPORARY TABLE merged_temp ( 列1 数据类型, 列2 数据类型 -- 按你实际的表结构补全所有列 ); -- 导入当前表数据 COPY INTO merged_temp FROM @source_current_stage; -- 追加导入历史表数据 COPY INTO merged_temp FROM @source_history_stage;
如果两张表存在重复数据需要去重,追加完数据后跑下面这句生成去重后的临时表,后续导出用这张表即可:
CREATE OR REPLACE TEMPORARY TABLE merged_dedup AS SELECT DISTINCT * FROM merged_temp;
步骤3:导出合并后的数据到目标S3
直接用COPY命令把临时表数据写到目标阶段就行,数据会自动写入目标S3路径:
COPY INTO @target_output_stage FROM merged_temp -- 如果做了去重就替换成merged_dedup HEADER = TRUE -- CSV格式需要保留表头就开这个参数 OVERWRITE = TRUE -- 需要覆盖目标路径下已有文件就开这个参数 ;
执行完后跑LIST @target_output_stage;确认文件都生成了,再去目标S3桶抽查下文件内容,整个迁移就完成了。
新手避坑提示
- 不要上来就跑全量导入,先拿LIMIT 10测数据读取是否正常,避免格式配错导了一堆脏数据
- 如果两张表的字段顺序不一致,COPY的时候不要默认按位置映射,手动写清楚字段对应关系,避免字段错位
- 单表数据量超过TB级的时候,可以给COPY命令加
PARALLEL参数提数,不过新手默认参数就够用,不用乱调 - 不要用永久表存中间合并数据,用完忘了删会一直算存储费,临时表免费且自动清理
内容的提问来源于stack exchange,提问作者Shanti Sharma
相关产品推荐
相关产品推荐

