我有一个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()
答案 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()
希望有帮助!