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

使用AWS Glue从S3向Redshift执行Upsert时临时表引用失败的问题排查

解决AWS Glue向Redshift Upsert时临时表不存在的问题

问题根源

你遇到的relation "public.#table_stg" does not exist错误,核心原因是AWS Glue会自动给未指定schema的dbtable参数添加public前缀,但Redshift的会话级临时表(以#开头)不允许携带任何schema前缀——临时表不属于任何用户定义的schema,而是存储在会话专属的临时空间中。Glue生成的COPY语句变成了COPY public.#my_table_stg ...,自然找不到对应的临时表。

解决方案

要让Glue正确处理Redshift临时表,只需修改一个关键配置,同时保持原有查询逻辑不变:

  1. 阻止Glue自动添加schema前缀
    在connection_options中添加"schema": ""(空字符串),这样Glue就不会给dbtable指定的临时表名自动追加public前缀,确保COPY语句直接使用不带schema的临时表名。

  2. 保持pre/post查询的正确性
    你原有的pre/post查询逻辑(创建空临时表、Upsert后删除)是正确的,因为这些查询里已经直接使用不带schema的临时表名,完全符合Redshift对临时表的使用要求。

修改后的完整代码

table_wo_schema = "my_table"
stg_table_name = f"#{table_wo_schema}_stg"
table_name = f"myschema.{table_wo_schema}"

# 保持原有的pre/post查询逻辑,临时表无schema前缀
pre_query = f"drop table if exists {stg_table_name};create table {stg_table_name} as select * from {table_name} where 1=2;"
post_query= f"delete from {table_name} using {stg_table_name} where {stg_table_name}.id = {table_name}.id ; insert into {table_name} select * from {stg_table_name}; drop table {stg_table_name};"

# 添加schema: "" 阻止Glue自动追加public前缀
glueContext.write_dynamic_frame.from_jdbc_conf(
    frame = dynamic_frame_to_write,
    catalog_connection = "my-redshift-connection",
    connection_options = {
        "preactions": pre_query,
        "dbtable": stg_table_name,
        "database": "my-redshift-database",
        "postactions": post_query,
        "schema": ""  # 关键配置:禁用自动schema前缀
    },
    redshift_tmp_dir = "s3://some/dir"
)

额外验证点

  • 确认Glue连接使用的Redshift用户拥有创建临时表的权限(默认情况下,只要用户有数据库的USAGE权限就能创建临时表)。
  • 临时表是会话级别的,只会在当前Glue任务的会话中存在,其他会话无法访问,完全符合你不想让staging表被外部访问的需求。

内容的提问来源于stack exchange,提问作者Gamaliel Ronzón

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 11:23:26