适用于Redshift的AWS Glue:重复的数据吗?

时间:2018-09-19 03:37:45

标签: python amazon-web-services amazon-s3 amazon-redshift aws-glue

关于我的设置方式,这里有一些要点:

我已将CSV文件上传到S3,并使用Glue搜寻器设置来创建表和架构。 我有一个Glue作业设置,它使用JDBC连接将数据从Glue表写入我们的Amazon Redshift数据库。 Job还负责映射列和创建redshift表。 通过重新运行作业,我在redshift中得到了重复的行(如预期的那样)。

但是,在插入新数据之前,有没有办法替换或删除行?

“书签”功能已启用,但不起作用。

在Python中将数据推送到redshift之前,如何连接到redshift,删除所有数据作为JOB的一部分?

5 个答案:

答案 0 :(得分:1)

当前,Glue不支持JDBC源书签。

您可以使用postactions选项(Scala中的代码)在Glue作业中实现upsert/merge into Redshift

val fields = sourceDf.columns.mkString(",")

glueContext.getJDBCSink(
  catalogConnection = "RedshiftConnectionTest",
  options = JsonOptions(Map(
    "database" -> "conndb",
    "dbtable" -> "staging_schema.staging_table",
    "postactions" -> 
        s"""
           DELETE FROM dst_schema.dst_table USING staging_schema.staging_table AS S WHERE dst_table.id = S.id;
           INSERT INTO dst_schema.dst_table ($fields) SELECT $fields FROM staging_schema.staging_table;
           DROP TABLE IF EXISTS staging_schema.staging_table
        """
  )),
  redshiftTmpDir = tempDir,
  transformationContext = "redshift-output"
).writeDynamicFrame(DynamicFrame(sourceDf, glueContext))

如果您只想删除现有表,则可以使用preactions参数:

glueContext.getJDBCSink(
  catalogConnection = "RedshiftConnectionTest",
  options = JsonOptions(Map(
    "database" -> "conndb",
    "dbtable" -> "dst_schema.dst_table",
    "preactions" -> "DELETE FROM dst_schema.dst_table"
  )),
  redshiftTmpDir = tempDir,
  transformationContext = "redshift-output"
).writeDynamicFrame(DynamicFrame(sourceDf, glueContext))

答案 1 :(得分:0)

只要您的表上有唯一键,最好是整数主键。 那么我解决这个问题的方法如下:

  1. 实施调度工具以允许按顺序运行作业。一世 推荐气流。
  2. 启动Glue作业以从源读取并写入暂存 表。 (登台表将仅包含该胶水运行的输出,不一定包含所有行)
  3. 等待该胶水作业完成(使用计划工具)
  4. 启动在Redshift上运行的SQL作业:

a)从目标表中删除匹配的行

delete from target
where id in (select id from staging);

b)将数据从登台插入到目标表中

insert into target select * from staging;

c)截断暂存表

d)抽空并分析两个表

vacuum target to 100 percent;
analyze target;
vacuum staging;

答案 2 :(得分:0)

您可以使用python模块pg8000来连接到Redfshift并执行SQL来从您的Glue脚本中删除(删除/截断)数据。 pg8000是纯Python,因此可与Glue一起使用。

查看此链接:AWS Glue - Truncate destination postgres table prior to insert

我已经尝试过了,效果很好。希望这对您有所帮助,

答案 3 :(得分:0)

如果您希望进行完全加载,则可以使用spark / Pyspark databricks库来覆盖表:

df.write\
  .format("com.databricks.spark.redshift")\
  .option("url", redshift_url)\
  .option("dbtable", redshift_table)\
  .option("user", user)\
  .option("password", readshift_password)\
  .option("aws_iam_role", redshift_copy_role)\
  .option("tempdir", args["TempDir"])\
  .mode("overwrite")\
  .save()

每个Databricks / Spark documentation

  

覆盖现有表:默认情况下,该库使用   事务以执行覆盖,通过删除来实现   目标表,创建一个新的空表并追加行   

您可以在here

中查看databricks文档

答案 4 :(得分:0)

Glue 作业确实支持使用 JDBC 源进行书签。这一切都取决于是否存在“增加”或“减少”的键(列)。

https://docs.aws.amazon.com/glue/latest/dg/monitor-continuations.html