def add_dataframe(
        self,
        dataframe,
        dataframe_name=None,
        index=None,
        logical_types=None,
        semantic_tags=None,
        make_index=False,
        time_index=None,
        secondary_time_index=None,
        already_sorted=False,
    ):
        """
        Add a DataFrame to the EntitySet with Woodwork typing information.

        Args:
            dataframe (pandas.DataFrame) : Dataframe containing the data.

            dataframe_name (str, optional) : Unique name to associate with this dataframe. Must be
                provided if Woodwork is not initialized on the input DataFrame.

            index (str, optional): Name of the column used to index the dataframe.
                Must be unique. If None, take the first column.

            logical_types (dict[str -> Woodwork.LogicalTypes/str, optional]):
                Keys are column names and values are logical types. Will be inferred if not specified.

            semantic_tags (dict[str -> str/set], optional):
                Keys are column names and values are semantic tags.

            make_index (bool, optional) : If True, assume index does not
                exist as a column in dataframe, and create a new column of that name
                using integers. Otherwise, assume index exists.

            time_index (str, optional): Name of the column containing
                time data. Type must be numeric or datetime in nature.

            secondary_time_index (dict[str -> list[str]]): Name of column containing time data to
                be used as a secondary time index mapped to a list of the columns in the dataframe
                associated with that secondary time index.

            already_sorted (bool, optional) : If True, assumes that input dataframe
                is already sorted by time. Defaults to False.

        Notes:

            Will infer logical types from the data.

        Example:
            .. ipython:: python

                import featuretools as ft
                import pandas as pd
                transactions_df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6],
                                                "session_id": [1, 2, 1, 3, 4, 5],
                                                "amount": [100.40, 20.63, 33.32, 13.12, 67.22, 1.00],
                                                "transaction_time": pd.date_range(start="10:00", periods=6, freq="10s"),
                                                "fraud": [True, False, True, False, True, True]})
                es = ft.EntitySet("example")
                es.add_dataframe(dataframe_name="transactions",
                                 index="id",
                                 time_index="transaction_time",
                                 dataframe=transactions_df)

                es["transactions"]

        """
        logical_types = logical_types or {}
        semantic_tags = semantic_tags or {}

        if len(self.dataframes) > 0:
            if not isinstance(dataframe, type(self.dataframes[0])):
                raise ValueError(
                    "All dataframes must be of the same type. "
                    "Cannot add dataframe of type {} to an entityset with existing dataframes "
                    "of type {}".format(type(dataframe), type(self.dataframes[0])),
                )

        # Only allow string column names
        non_string_names = [
            name for name in dataframe.columns if not isinstance(name, str)
        ]
        if non_string_names:
            raise ValueError(
                "All column names must be strings (Columns {} "
                "are not strings)".format(non_string_names),
            )

        if dataframe.ww.schema is None:
            if dataframe_name is None:
                raise ValueError(
                    "Cannot add dataframe to EntitySet without a name. "
                    "Please provide a value for the dataframe_name parameter.",
                )

            index_was_created, index, dataframe = _get_or_create_index(
                index,
                make_index,
                dataframe,
            )

            dataframe.ww.init(
                name=dataframe_name,
                index=index,
                time_index=time_index,
                logical_types=logical_types,
                semantic_tags=semantic_tags,
                already_sorted=already_sorted,
            )
            if index_was_created:
                dataframe.ww.metadata["created_index"] = index

        else:
            if dataframe.ww.name is None:
                raise ValueError(
                    "Cannot add a Woodwork DataFrame to EntitySet without a name",
                )
            if dataframe.ww.index is None:
                raise ValueError(
                    "Cannot add Woodwork DataFrame to EntitySet without index",
                )

            extra_params = []
            if index is not None:
                extra_params.append("index")
            if time_index is not None:
                extra_params.append("time_index")
            if logical_types:
                extra_params.append("logical_types")
            if make_index:
                extra_params.append("make_index")
            if semantic_tags:
                extra_params.append("semantic_tags")
            if already_sorted:
                extra_params.append("already_sorted")
            if dataframe_name is not None and dataframe_name != dataframe.ww.name:
                extra_params.append("dataframe_name")
            if extra_params:
                warnings.warn(
                    "A Woodwork-initialized DataFrame was provided, so the following parameters were ignored: "
                    + ", ".join(extra_params),
                )

        if dataframe.ww.time_index is not None:
            self._check_uniform_time_index(dataframe)
            self._check_secondary_time_index(dataframe)

        if secondary_time_index:
            self._set_secondary_time_index(
                dataframe,
                secondary_time_index=secondary_time_index,
            )

        dataframe = self._normalize_values(dataframe)

        self.dataframe_dict[dataframe.ww.name] = dataframe
        self.reset_data_description()
        self._add_references_to_metadata(dataframe)

        return self

        Add a DataFrame to the EntitySet with Woodwork typing information.

        Args:
            dataframe (pandas.DataFrame) : Dataframe containing the data.

            dataframe_name (str, optional) : Unique name to associate with this dataframe. Must be
                provided if Woodwork is not initialized on the input DataFrame.

            index (str, optional): Name of the column used to index the dataframe.
                Must be unique. If None, take the first column.

            logical_types (dict[str -> Woodwork.LogicalTypes/str, optional]):
                Keys are column names and values are logical types. Will be inferred if not specified.

            semantic_tags (dict[str -> str/set], optional):
                Keys are column names and values are semantic tags.

            make_index (bool, optional) : If True, assume index does not
                exist as a column in dataframe, and create a new column of that name
                using integers. Otherwise, assume index exists.

            time_index (str, optional): Name of the column containing
                time data. Type must be numeric or datetime in nature.

            secondary_time_index (dict[str -> list[str]]): Name of column containing time data to
                be used as a secondary time index mapped to a list of the columns in the dataframe
                associated with that secondary time index.

            already_sorted (bool, optional) : If True, assumes that input dataframe
                is already sorted by time. Defaults to False.

        Notes:

            Will infer logical types from the data.

        Example:
            .. ipython:: python

                import featuretools as ft
                import pandas as pd
                transactions_df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6],
                                                "session_id": [1, 2, 1, 3, 4, 5],
                                                "amount": [100.40, 20.63, 33.32, 13.12, 67.22, 1.00],
                                                "transaction_time": pd.date_range(start="10:00", periods=6, freq="10s"),
                                                "fraud": [True, False, True, False, True, True]})
                es = ft.EntitySet("example")
                es.add_dataframe(dataframe_name="transactions",
                                 index="id",
                                 time_index="transaction_time",
                                 dataframe=transactions_df)

                es["transactions"]

        
featuretools/entityset/entityset.py