Исключение AnalysisException выдается, когда фрейм данных пуст (нет такого поля структуры)

#scala #apache-spark #databricks

#scala #apache-spark #блоки данных

Вопрос:

У меня есть фрейм данных, к которому я применяю фильтр, а затем серию преобразований. В конце я выбираю несколько столбцов.

 //  Filters the event related to a user_principal.
  var filteredCount = events.filter("Properties.EventTypeName == 'user_principal_created' or Properties.EventTypeName == 'user_principal_updated'");
                            // Selects the columns based on the event type.
                            .withColumn("Username", when(col("Properties.EventTypeName") === lit("user_principal_created"), col("Body.Username"))
                            .otherwise(col("Body.NewValue.Username")))
                            .withColumn("FirstName", when(col("Properties.EventTypeName") === lit("user_principal_created"), col("Body.FirstName"))
                            .otherwise(col("Body.NewValue.FirstName")))
                            .withColumn("LastName", when(col("Properties.EventTypeName") === lit("user_principal_created"), col("Body.LastName"))
                            .otherwise(col("Body.NewValue.LastName")))
                            .withColumn("PrincipalId", when(col("Properties.EventTypeName") === lit("user_principal_created"), col("Body.PrincipalId"))
                            .otherwise(col("Body.NewValue.PrincipalId")))
                            .withColumn("TenantId", when(col("Properties.EventTypeName") === lit("user_principal_created"), col("Body.TenantId"))
                            .otherwise(col("Body.NewValue.TenantId")))
                            .withColumnRenamed("Timestamp", "LastChangeTimestamp")
                            // Create the custom primary key.
                            .withColumn("PrincipalUserId", substring(concat(col("TenantId"), lit("-"), col("PrincipalId")), 0, 128))                           
                            // Select the rows.
                            .select("PrincipalUserId", "TenantId", "PrincipalId", "FirstName", "LastName", "Username", "LastChangeTimestamp")
  

Это работает, только если в events есть строки, соответствующие фильтру. Если ни одна строка не соответствует фильтру, то я получаю следующее исключение:

org.apache.spark.sql.AnalysisException: нет такого имени пользователя в поле структуры…

Вопрос

Что я могу сделать, чтобы обработать такой сценарий и предотвратить withColumn сбой?

Обновить

Вот логический план, когда это работает:

== Проанализированный логический план == Тело: struct,CitationNumber:string,Color:string,CommitReference:string,ContactAddress:struct,ControlId:string,Data:string,Dependencies:array>,Description:string,DeviceId:string,Error:bigint,ErrorDetails:string,Exemption:struct,ExternalId:string,FeatureId:string,Features:array,FirstName:string,GroupPrincipals:array,GroupType:bigint,Id:bigint,IsAuthorized:boolean,IsDedicatedStorage:boolean,IsEnabled:boolean,IsInitialCreation:boolean, … еще 33 поля>, Идентификатор: строка, Свойства: структура, временная метка: строковое отношение[Тело #248, идентификатор # 249, Свойства # 250, временная метка # 251] json

И когда генерируется исключение:

== Проанализированный логический план == Тело: struct,Id:bigint,IsAuthorized:boolean,Latitude:double,Longitude:double,Name:string,NewValue:struct,OldValue:struct,Ordinal:bigint,ParentZoneId:string,PrincipalId:bigint,PrincipalName:string,Requirements:array,FeatureId:string,RequirementId:string,ServiceId:string>>,FeatureId:string,RequirementId:string,ServiceId:string>>,RestrictedZoneId:bigint,StreetName:string,TenantId:string,Timestamp:string,… еще 2 поля>, Идентификатор: строка, Свойства: структура, временная метка: строковое отношение [Тело #44, идентификатор#45, Свойства # 46, временная метка # 47] json

Комментарии:

1. It works only if the filter does return rows — Spark работает не так. Либо вы обнаружили ошибку в Spark, либо ваш анализ неверен. Последнее более вероятно 🙂 Пожалуйста, добавьте логический план.

2. Что я вижу, так это то, что это работает, когда в events есть строки, соответствующие тому, что есть в фильтре. Однако, когда совпадений нет, я получаю исключение. Я перепишу предложение, чтобы избежать потенциальной путаницы.

3. Пожалуйста, добавьте логический план, ответ должен быть прямо там. events.explain(true) , для обоих случаев.

4. Нет решения по этой проблеме?

5. Я думаю, что я сталкиваюсь с той же ошибкой