[Python] Enforcing Schema for PySpark Job

Discussão em 'Python' iniciado por Stack, Abril 20, 2025.

  1. Stack

    Stack Membro Participativo

    We have a bunch of disparate pyspark jobs and have a usecase where two jobs can be chained together to form a seperate 3rd job. So if you have one job 'A' and another job 'B' these jobs can be chained together to form another job 'C'. Obviously this can only happen if the output dataframe schema from 'A' is compatible with dataframe schema to 'B'. This is exactly what the dataset api achieves however unfortunately spark doesnt vend dataset for python, understandably because python is dynamically typed. However with the advent of typings we can achieve some sort of compile time safety and I can think of a couple of ways to achieve this, one through composition the other through inheritance.
    Composition

    from typing import TypeVar, Generic
    from pyspark.sql import DataFrame
    from enum import Enum

    #Marker Enum
    class Schema(Enum):
    pass

    T = TypeVar("T", bound = Schema)

    class CustomDataSet(Generic[T]):
    def __init__(self, dataframe: DataFrame) -> None:
    self.dataframe = dataframe



    Now I can use mypy and use composition like CustomDataSet[MySchema](dataframe). The problem out here is that MySchema is not dataframe object and this can be confusing to someone using this.

    Inheritance

    import abc
    from enum import Enum

    #Marker Enum
    class Schema(Enum):
    pass

    class MyInterface(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def get_input_schema() -> Schema:
    raise NotImplementedError

    @abc.abstractmethod
    def get_output_schema() -> Schema:
    raise NotImplementedError



    Now the two jobs 'A' and 'B' can implement the above interface. This seems a fairly verbose way of doing things and feel not a fan of Inheritance .

    My question I have is there a more pythonic way of doing this preferably where I can use composition?

    Continue reading...

Compartilhe esta Página