在Azure Databricks中使用pyspark将数据加载到Azure Synapse表时,无法将“int”值摄取到“bigint”列中

nuypyhwy  于 2023-04-05  发布在  Spark
关注(0)|答案(1)|浏览(182)

我最近在Azure Synapse中将列的数据类型从int更改为bigint,因为传入的数据包含更大的值。但是当我尝试执行一些新的加载时,我现在得到以下错误:

Underlying SQLException(s):
  - com.microsoft.sqlserver.jdbc.SQLServerException: HdfsBridge::recordReaderFillBuffer - Unexpected error encountered filling record reader buffer: ClassCastException: class java.lang.Integer cannot be cast to class java.lang.Long (java.lang.Integer and java.lang.Long are in module java.base of loader 'bootstrap') [ErrorCode = 106000] [SQLState = S0001]

我对这个错误感到惊讶,因为理想情况下,int值应该在bigint列中自动兼容。但显然pyspark似乎不这么认为。我不知道为什么。
我还检查了databricks集群中以下spark配置的当前设置:

spark.conf.get("spark.sql.storeAssignmentPolicy") #outputs: 'Legacy'
spark.sql.ansi.enabled #outputs: 'false'

但是,当我在SQL Server Management Studio(SSMS)中使用INSERT INTO查询手动执行插入时,其中一个示例记录使用Azure Synapse中bigint列的int值,它成功插入了它。
所以,在使用Databricks的df.write()执行此操作时,可能会出现问题。我不确定问题出在哪里,以及我可以做些什么来纠正它们。
有没有人帮忙?

1bqhqjot

1bqhqjot1#

一个可能的解决方案是在写入数据库之前将数据框中的整数列转换为long。
例如,使用cast() function定义数据框。

如果要更改单列,将整数转换为long:
代码如下:

df1 = df.withColumn("id", col("id").cast("long"))

多列强制转换代码如下:

from pyspark.sql.functions import col

df = df.select([col(c).cast('long') if t == 'int'  else col(c) for c, t in df.dtypes])

或者

可以使用for循环迭代数据框架构中的所有列。

样品代码:

for field in df.schema.fields:
    if  isinstance(field.dataType, IntegerType):
        df = df.withColumn(field.name, col(field.name).cast(LongType()))

相关问题