class_docstr: Reuses PrestoEngineSpec functionality.
class_docstr_tok: ["Reuses","PrestoEngineSpec","functionality","."]
docstr: Upload data from a Pandas DataFrame to a database.
  
  The data is stored via the binary Parquet format which is both less problematic
  and more performant than a text file. More specifically storing a table as a
  CSV text file has severe limitations including the fact that the Hive CSV SerDe
  does not support multiline fields.
  
  Note this method does not create metadata for the table.
  
  :param database: The database to upload the data to
  :param: table The table to upload the data to
  :param df: The dataframe with data to be uploaded
  :param to_sql_kwargs: The kwargs to be passed to pandas.DataFrame.to_sql` method
docstr_tok: ["Upload","data","from","a","Pandas","DataFrame","to","a","database",".","The","data","is","stored","via","the","binary","Parquet","format","which","is","both","less","problematic","and","more","performant","than","a","text","file",".","More","specifically","storing","a","table","as","a","CSV","text","file","has","severe","limitations","including","the","fact","that","the","Hive","CSV","SerDe","does","not","support","multiline","fields",".","Note","this","method","does","not","create","metadata","for","the","table",".",":","param","database",":","The","database","to","upload","the","data","to",":","param",":","table","The","table","to","upload","the","data","to",":","param","df",":","The","dataframe","with","data","to","be","uploaded",":","param","to_sql_kwargs",":","The","kwargs","to","be","passed","to","pandas.DataFrame.to_sql","`","method"]
code: def df_to_sql(
      cls,
      database: Database,
      table: Table,
      df: pd.DataFrame,
      to_sql_kwargs: dict[str, Any],
  ) -> None:
      """
      Upload data from a Pandas DataFrame to a database.
  
      The data is stored via the binary Parquet format which is both less problematic
      and more performant than a text file. More specifically storing a table as a
      CSV text file has severe limitations including the fact that the Hive CSV SerDe
      does not support multiline fields.
  
      Note this method does not create metadata for the table.
  
      :param database: The database to upload the data to
      :param: table The table to upload the data to
      :param df: The dataframe with data to be uploaded
      :param to_sql_kwargs: The kwargs to be passed to pandas.DataFrame.to_sql` method
      """
  
      if to_sql_kwargs["if_exists"] == "append":
          raise SupersetException(
              "Append operation not currently supported"
          )
  
      if to_sql_kwargs["if_exists"] == "fail":
          # Ensure table doesn't already exist.
          if table.schema:
              table_exists = not database.get_df(
                  f"SHOW TABLES IN {table.schema} LIKE '{table.table}'"
              ).empty
          else:
              table_exists = not database.get_df(
                  f"SHOW TABLES LIKE '{table.table}'"
              ).empty
  
          if table_exists:
              raise SupersetException("Table already exists")
      elif to_sql_kwargs["if_exists"] == "replace":
          with cls.get_engine(database) as engine:
              engine.execute(f"DROP TABLE IF EXISTS {str(table)}")
  
      def _get_hive_type(dtype: np.dtype[Any]) -> str:
          hive_type_by_dtype = {
              np.dtype("bool"): "BOOLEAN",
              np.dtype("float64"): "DOUBLE",
              np.dtype("int64"): "BIGINT",
              np.dtype("object"): "STRING",
          }
  
          return hive_type_by_dtype.get(dtype, "STRING")
  
      schema_definition = ", ".join(
          f"`{name}` {_get_hive_type(dtype)}"
          for name, dtype in df.dtypes.items()
      )
  
      with tempfile.NamedTemporaryFile(
          dir=current_app.config["UPLOAD_FOLDER"], suffix=".parquet"
      ) as file:
          pq.write_table(pa.Table.from_pandas(df), where=file.name)
  
          with cls.get_engine(database) as engine:
              engine.execute(
                  text(
                      f"""
                          CREATE TABLE {str(table)} ({schema_definition})
                          STORED AS PARQUET
                          LOCATION :location
                          """
                  ),
                  location=upload_to_s3(
                      filename=file.name,
                      upload_prefix=current_app.config[
                          "CSV_TO_HIVE_UPLOAD_DIRECTORY_FUNC"
                      ](database, g.user, table.schema),
                      table=table,
                  ),
              )
  
imports: from __future__ import annotations
  import logging
  import os
  import re
  import tempfile
  import time
  from datetime import datetime
  from typing import Any, TYPE_CHECKING
  from urllib import parse
  import numpy
  import pandas
  import pyarrow
  import pyarrow.parquet
  from flask import current_app, g
  from sqlalchemy import Column, text, types
  from sqlalchemy.engine.base import Engine
  from sqlalchemy.engine.reflection import Inspector
  from sqlalchemy.engine.url import URL
  from sqlalchemy.sql.expression import ColumnClause, Select
  from superset import db
  from superset.common.db_query_status import QueryStatus
  from superset.constants import TimeGrain
  from superset.databases.utils import make_url_safe
  from superset.db_engine_specs.base import BaseEngineSpec
  from superset.db_engine_specs.presto import PrestoEngineSpec
  from superset.exceptions import SupersetException
  from superset.extensions import cache_manager
  from superset.models.sql_lab import Query
  from superset.sql_parse import ParsedQuery, Table
  from superset.superset_typing import ResultSetColumnType
label_desc: Use image node_id 3 for calling the HiveEngineSpec obj's underlying member method code with example usage: obj.df_to_sql(cls, database, table, df, to_sql_kwargs) and returns: hive_type_by_dtype