def cast_dataframe_for_parquet(
    dataframe: pandas.DataFrame,
    schema: Optional[Dict[str, Any]],
) -> pandas.DataFrame:
    """Cast columns to needed dtype when writing parquet files.

    See: https://github.com/googleapis/python-bigquery-pandas/issues/421
    """

    columns = schema.get("fields", [])

    # Protect against an explicit None in the dictionary.
    columns = columns if columns is not None else []

    for column in columns:
        # Schema can be a superset of the columns in the dataframe, so ignore
        # columns that aren't present.
        column_name = column.get("name")
        if column_name not in dataframe.columns:
            continue

        # Skip array columns for now. Potentially casting the elements of the
        # array would be possible, but not worth the effort until there is
        # demand for it.
        if column.get("mode", "NULLABLE").upper() == "REPEATED":
            continue

        column_type = column.get("type", "").upper()
        if (
            column_type == "DATE"
            # Use extension dtype first so that it uses the correct equality operator.
            and db_dtypes.DateDtype() != dataframe[column_name].dtype
        ):
            cast_column = dataframe[column_name].astype(
                dtype=db_dtypes.DateDtype(),
                # Return the original column if there was an error converting
                # to the dtype, such as is there is a date outside the
                # supported range.
                # https://github.com/googleapis/python-bigquery-pandas/issues/441
                errors="ignore",
            )
        elif column_type in {"NUMERIC", "DECIMAL", "BIGNUMERIC", "BIGDECIMAL"}:
            # decimal.Decimal does not support `None` or `pandas.NA` input, add
            # support here.
            # https://github.com/googleapis/python-bigquery-pandas/issues/719
            def convert(x):
                if pandas.isna(x):  # true for `None` and `pandas.NA`
                    return decimal.Decimal("NaN")
                else:
                    return decimal.Decimal(x)

            cast_column = dataframe[column_name].map(convert)
        elif column_type == "STRING":
            # Allow non-string columns to be uploaded to STRING in BigQuery.
            # https://github.com/googleapis/python-bigquery-pandas/issues/875
            # TODO: Use pyarrow as the storage when the minimum pandas version allows for it.
            cast_column = dataframe[column_name].astype(pandas.StringDtype())
        else:
            cast_column = None

        if cast_column is not None:
            dataframe = dataframe.assign(**{column_name: cast_column})
    return dataframe
Cast columns to needed dtype when writing parquet files.

    See: https://github.com/googleapis/python-bigquery-pandas/issues/421
    
pandas_gbq/load/core.py