Databricks версии 7.0 не ведет себя как версия 6.3: класс java.lang.Long не может быть преобразован в класс java.lang.Integer

У меня есть рабочий блокнот на лазурных модулях версии 6.3 - Spark 2.4.4

Эта записная книжка выполняет прием данных в Azure Synapse Analytics с помощью своего коннектора.

Когда я обновил ноутбук до версии 7.0 - Spark 3.0.0, процесс начал давать сбой со следующей ошибкой:

com.microsoft.sqlserver.jdbc.SQLServerException: HdfsBridge :: recordReaderFillBuffer - Произошла непредвиденная ошибка при заполнении буфера чтения записи: ClassCastException: класс java.lang.Long не может быть преобразован в класс java.lang.Integer (java.lang.Long и java. lang.Integer находятся в модуле java.base загрузчика bootstrap) [ErrorCode = 106000] [SQLState = S0001]

Это схема таблицы в Synapse Analytics:

CREATE TABLE [dbo].[IncrementalDestination]
(
[Id] [int] NOT NULL,
[VarChar] [varchar](1000) NULL,
[Char] [char](1000) NULL,
[Text] [varchar](1000) NULL,
[NVarChar] [nvarchar](1000) NULL,
[NChar] [nchar](1000) NULL,
[NText] [nvarchar](1000) NULL,
[Date] [date] NULL,
[Datetime] [datetime] NULL,
[Datetime2] [datetime2](7) NULL,
[Smalldatetime] [smalldatetime] NULL,
[Bigint] [bigint] NULL,
[Bit] [bit] NULL,
[Decimal] [decimal](18, 0) NULL,
[Int] [int] NULL,
[Money] [money] NULL,
[Numeric] [numeric](18, 0) NULL,
[Smallint] [smallint] NULL,
[Smallmoney] [smallmoney] NULL,
[Tinyint] [tinyint] NULL,
[Float] [float] NULL,
[Real] [real] NULL,
[Column With Space] [varchar](1000) NULL,
[Column_ç_$pecial_char] [varchar](1000) NULL,
[InsertionDateUTC] [datetime] NOT NULL,
[De_LastUpdated] [datetime2](3) NOT NULL
)
WITH
(
DISTRIBUTION = ROUND_ROBIN,
CLUSTERED COLUMNSTORE INDEX
)
GO

Это схема, созданная Databricks после чтения группы паркетов в Azure BlobStorage.

root
 |-- Id: long (nullable = true)
 |-- VarChar: string (nullable = true)
 |-- Char: string (nullable = true)
 |-- Text: string (nullable = true)
 |-- NVarChar: string (nullable = true)
 |-- NChar: string (nullable = true)
 |-- NText: string (nullable = true)
 |-- Date: timestamp (nullable = true)
 |-- Datetime: timestamp (nullable = true)
 |-- Datetime2: timestamp (nullable = true)
 |-- Smalldatetime: timestamp (nullable = true)
 |-- Bigint: long (nullable = true)
 |-- Bit: boolean (nullable = true)
 |-- Decimal: long (nullable = true)
 |-- Int: long (nullable = true)
 |-- Money: double (nullable = true)
 |-- Numeric: long (nullable = true)
 |-- Smallint: long (nullable = true)
 |-- Smallmoney: double (nullable = true)
 |-- Tinyint: long (nullable = true)
 |-- Float: double (nullable = true)
 |-- Real: double (nullable = true)
 |-- Column_With_Space: string (nullable = true)
 |-- Column_ç_$pecial_char: string (nullable = true)
 |-- InsertionDateUTC: timestamp (nullable = true)
 |-- De_LastUpdated: timestamp (nullable = false)

я видел это

Int: long (nullable = true)

Но что я могу сделать?

Разве это преобразование не должно быть естественным и простым?

Я думаю, что что-то сломалось с этими новыми функциями =]


person Flavio Pegas    schedule 20.06.2020    source источник


Ответы (1)


Я считаю, что это вызвано следующим изменением: описано в руководстве по переходу:

В Spark 3.0 при вставке значения в столбец таблицы с другим типом данных приведение типа выполняется в соответствии со стандартом ANSI SQL. Некоторые необоснованные преобразования типов, такие как преобразование строки в int и double в логическое значение, запрещены. Исключение времени выполнения создается, если значение выходит за пределы диапазона для типа данных столбца. В Spark версии 2.4 и ниже преобразования типов во время вставки таблицы разрешены, если они действительны Cast . При вставке значения вне диапазона в целочисленное поле вставляются младшие биты значения (то же самое, что и приведение числового типа Java / Scala). Например, если 257 вставлено в поле байтового типа, результатом будет 1. Поведение контролируется опцией spark.sql.storeAssignmentPolicy со значением по умолчанию как «ANSI». Установка для параметра «Наследие» восстанавливает предыдущее поведение.

Таким образом, вы можете попробовать установить spark.sql.storeAssignmentPolicy на Legacy и повторно запустить код.

person Alex Ott    schedule 22.06.2020
comment
Похоже, вы нашли основание, но мне любопытно, мой поток тестирования: таблица sqlserver - ›паркет -› databricks - ›таблица dw. Таблица сервера sql и таблица dw одинаковы. Я не понимаю, как это могло привести к исключению вне допустимого диапазона - person Flavio Pegas; 22.06.2020
comment
Я обнаружил, что мой процесс извлечения преобразует int в long, но, к сожалению, spark.conf.set (spark.sql.storeAssignmentPolicy, Legacy) не работал - person Flavio Pegas; 22.06.2020