es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Parquet con columnas nulas en Pyarrow

Estoy leyendo una tabla en PostgreSQL utilizando pandas.read_sql, luego la convierto en una tabla de Pyarrow y la guardo particionada en el sistema de archivos local.

Recuperar datos de schema.tabla de la base de datos

def basename_file(date_partition):
basename_file = f”{table_schema}.{table_name}-{date}.parquet”
return basename_file

def obtener_datos_tabla(table_schema, table_name, date):
s = “”
s += “SELECT”
s += ” *”
s += ” , date(created_on) as date_partition”
s += f” FROM {table_schema}.{table_name}”
s += f” WHERE created_on = ‘{date}’;”
sql = s.format(table_schema=table_schema, table_name=table_name, date=date)

df = pd.read_sql(sql, db_conn)
result = pa.Table.from_pandas(df)
pq.write_to_dataset(result,
                    root_path=f"{dir_name}",
                    partition_cols=['date_partition'],
                    partition_filename_cb=basename_file,
                    use_legacy_dataset=True
                   )
return df

El problema es que mi consulta SELECT tiene una columna con algunas filas nulas. Cuando particiono esto para escribirlo (write_to_dataset) en el sistema de archivos local, algunos archivos solo tienen filas con esa columna nula, por lo que los archivos Parquet particionados no tienen esta columna.

Cuando intento leerlo por múltiples particiones, obtengo un error de esquema porque una de las columnas no se puede convertir correctamente.

¿Por qué sucede esto? ¿Hay alguna configuración que pueda aplicar a write_to_dataset para manejar esto? He estado buscando una solución alternativa para esto sin éxito…
Mi objetivo principal aquí es exportar los datos diariamente, particionados por fecha de transacción y leer los datos de cualquier período necesario, sin preocuparme por la evolución del esquema: de esta manera, el valor de fila para las columnas nulas aparecerá como nulo, simplemente eso.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Parece que el problema está relacionado con el mecanismo de inferencia de tipo de Pyarrow, que intenta inferir el tipo de datos de cada columna en función de los datos de las primeras filas. Si algunas de las filas tienen valores nulos para una columna en particular, la inferencia de tipo puede fallar e inferir incorrectamente el tipo de datos para esa columna.

    Una solución alternativa podría ser especificar explícitamente el tipo de datos de la columna problemática al crear la tabla de Pyarrow a partir del dataframe de Pandas. Por ejemplo, si se supone que la columna es de tipo string, puedes establecer el tipo de datos en “string” utilizando el siguiente código:

    import pyarrow as pa
    
    # Suponiendo que tu dataframe tiene una columna llamada "problem_column"
    problem_col_dtype = pa.string()
    table_schema = pa.schema([(col, problem_col_dtype) if col == 'problem_column' else (col, pa.from_numpy_dtype(dtype)) for col, dtype in df.dtypes.iteritems()])
    result = pa.Table.from_pandas(df, schema=table_schema)
    

    Esto asegurará que la tabla de Pyarrow tenga el tipo de datos correcto para la columna problemática, incluso si algunas de las filas tienen valores nulos.

    Otro enfoque podría ser llenar los valores nulos con algún valor predeterminado antes de crear la tabla de Pyarrow. Por ejemplo, si se supone que la columna debe contener strings y quieres tratar los valores nulos como cadenas vacías, puedes usar el siguiente código:

    df['problem_column'] = df['problem_column'].fillna('')
    result = pa.Table.from_pandas(df)
    

    Esto asegurará que la tabla de Pyarrow no tenga valores nulos en la columna problemática, lo que puede ayudar con la inferencia de tipo.

    En cualquier caso, es importante asegurarse de que la tabla de Pyarrow tenga el esquema correcto antes de particionarla y guardarla en disco. Esto puede ayudar a evitar errores de esquema al leer los datos particionados más adelante.

Comments are closed.