redshift胶作业bigint问题

时间:2019-12-19 12:27:55

标签: amazon-web-services pyspark amazon-redshift aws-glue

我有一个redshi9ft数据库。在数据库中,我创建了一个表,在表中,我有一个bigint列。我创建了一个胶水作业以将数据插入到redshift中。但是问题出在bigint领域。它没有插入。似乎bigint有问题。作业代码如下。我正在使用python 3和spark 2.2,

import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job

args = getResolvedOptions(sys.argv, ['TempDir','JOB_NAME'])

sc = SparkContext()
glueContext = GlueContext(sc)
 spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)

datasource0 = glueContext.create_dynamic_frame.from_catalog(database = "test", table_name = 
"tbl_test", transformation_ctx = "datasource0")

applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [("testdata", "string", 
 "testdata", "string"), ("selling", "bigint", "selling", "bigint")], transformation_ctx = "applymapping1")

resolvechoice2 = ResolveChoice.apply(frame = applymapping1, choice = "make_cols", 
 transformation_ctx = "resolvechoice2")

dropnullfields3 = DropNullFields.apply(frame = resolvechoice2, transformation_ctx = 
"dropnullfields3")

 datasink4 = glueContext.write_dynamic_frame.from_jdbc_conf(frame = dropnullfields3, 
 catalog_connection = "redshift_con", connection_options = {"dbtable": "tbl_test", 
 "database": "test"}, redshift_tmp_dir = args["TempDir"], transformation_ctx = "datasink4")
 job.commit()

3 个答案:

答案 0 :(得分:1)

尝试使用映射:(“销售”,“ int”,“销售”,“多头”)

如果这不起作用,则应张贴Glue目录中的“ tbl_test”定义。您的ApplyMapping中的第一种类型应与目录的表定义中列出的类型匹配。

我有一个类似的问题,结果是控制台中的Glue Crawler在胶水表上创建的类型是'int',而不是'long',因此ApplyMapping必须是(“ fieldName”,“ int” ,“ fieldName”,“ long”)在Redshift类型“ bigint”的粘胶作业中。

有趣的是,当我将ApplyMapping设置为(“ field”,“ long”,“ field”,“ long”)时,它使我可以将值保留在Glue DynamicFrame中,甚至在打印之前将其打印到日志中,但不会将数据写入Redshift。

希望这会有所帮助!

答案 1 :(得分:0)

尝试在ApplyMapping调用中将类型强制转换为“ long”。如果您的粘贴作业在写入Redshift时没有失败,则有时会创建一个具有相同名称和redshift数据类型的新列。在这种情况下,selling_long

Spark到Redshift的映射可以在jdbc驱动程序here中找到。

|  Spark Type   |        JDBC Type         |
|---------------|--------------------------|
| IntegerType   | INTEGER                  |
| LongType      | BIGINT                   |
| DoubleType    | DOUBLE PRECISION         |
| FloatType     | REAL                     |
| ShortType     | INTEGER                  |
| ByteType      | SMALLINT                 |
| BooleanType   | BOOLEAN                  |
| StringType    | [VARCHAR|TEXT]           |
| TimestampType | TIMESTAMP                |
| DateType      | DATE                     |
| DecimalType   | DECIMAL(precision,scale) |

答案 2 :(得分:0)

我们遇到了同样的问题,使用int和bigint导入值只会导致提供两种数据类型之一。
我们通过以下解决方案解决了这个问题:

1)确保粘合搜寻器中的源表的数据类型具有“ bigint”
2)确保此行代码在您的Glue作业中:

applymapping1 = ApplyMapping.apply(frame = datasource0, mappings = [("testdata", "string", "testdata", "string"), ("selling", "long", "selling", "long")], transformation_ctx = "applymapping1")

3)经过步骤2和所有内容,直到dropnullfields3(这是我们最终的解决方案),您必须使用以下代码行再次强制转换为

castedFrame = dropnullfields3.resolveChoice(specs = [('selling','cast:long')])

4)现在,您可以简单地将此DF用于最终的装载线:

datasink4 = glueContext.write_dynamic_frame.from_jdbc_conf(frame = castedFrame, catalog_connection = "redshift_con", connection_options = {"dbtable": "tbl_test", "database": "test"}, redshift_tmp_dir = args["TempDir"], transformation_ctx = "datasink4") job.commit()

希望有帮助!