Не удалось получить атрибут «ClassName» в модуле «__main__» из воздушного потока - PullRequest
0 голосов
/ 24 октября 2019

Я использую Воздушный поток для организации моего конвейера данных. В одной из задач я пытаюсь загрузить маринованный объект (RouteModel экземпляр) из S3:

def read_file_from_s3(bucket, file):
    from inference.route_model import RouteModel

    s3_loader = S3Client(bucket, None)
    buffer = s3_loader.get_file(file)

    data = pickle.loads(buffer.read())

, что дает мне эту ошибку:

Traceback (most recent call last):
  File "/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/env/lib/python3.6/site-packages/airflow/models/taskinstance.py", line 926, in _run_raw_task
    result = task_copy.execute(context=context)
  File "/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/env/lib/python3.6/site-packages/airflow/operators/python_operator.py", line 113, in execute
    return_value = self.execute_callable()
  File "/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/env/lib/python3.6/site-packages/airflow/operators/python_operator.py", line 118, in execute_callable
    return self.python_callable(*self.op_args, **self.op_kwargs)
  File "/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/inference/predict.py", line 43, in get_pred_for_flight
    pred_state, pred_state_prob, pred_dt = tst_pipeline.get_prediction(format_pred_od)
  File "/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/inference/pipeline.py", line 174, in get_prediction
    route_model = self.rm_loader.get_model(self.rm_dict[r_key]['rm_key'])
  File "/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/inference/dataloader.py", line 40, in get_model
    route_model = read_file_from_s3(self.loc, fname)
  File "/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/inference/dataloader.py", line 96, in read_file_from_s3
    data = pickle.loads(buffer.read())
AttributeError: Can't get attribute 'RouteModel' on <module '__main__' from '/Users/cyrusghazanfar/Desktop/startup-studio/pilota_project/pilota_ml/env/bin/airflow'>

При работепри использовании пользовательских классов выбираемый класс должен появиться в пространстве имен процесса, считывающего этот параметр, в данном случае это «Поток воздуха».

ПРИМЕЧАНИЕ:

Я не могу изменить способ, которым я производил обработку файла

помогите пожалуйста:)

1 Ответ

0 голосов
/ 24 октября 2019

Чтобы решить эту проблему, мне нужно было написать собственный настраиваемый unpickler, в котором я явно возвращаю настраиваемый класс конкретного экземпляра, на который ссылается и файл pickle:

class CustomUnpickler(pickle.Unpickler):

    def find_class(self, module, name):
        if name == 'RouteModel':
            from inference.route_model import RouteModel
            return RouteModel
        return super().find_class(module, name)

 data = CustomUnpickler(io.BytesIO(buffer.read())).load()
...