def add_relationship(
        self,
        parent_dataframe_name=None,
        parent_column_name=None,
        child_dataframe_name=None,
        child_column_name=None,
        relationship=None,
    ):
        """Add a new relationship between dataframes in the entityset. Relationships can be specified
        by passing dataframe and columns names or by passing a :class:`.Relationship` object.

        Args:
            parent_dataframe_name (str): Name of the parent dataframe in the EntitySet. Must be specified
                if relationship is not.
            parent_column_name (str): Name of the parent column. Must be specified if relationship is not.
            child_dataframe_name (str): Name of the child dataframe in the EntitySet. Must be specified
                if relationship is not.
            child_column_name (str): Name of the child column. Must be specified if relationship is not.
            relationship (Relationship): Instance of new relationship to be added. Must be specified
                if dataframe and column names are not supplied.
        """
        if relationship and (
            parent_dataframe_name
            or parent_column_name
            or child_dataframe_name
            or child_column_name
        ):
            raise ValueError(
                "Cannot specify dataframe and column name values and also supply a Relationship",
            )

        if not relationship:
            relationship = Relationship(
                self,
                parent_dataframe_name,
                parent_column_name,
                child_dataframe_name,
                child_column_name,
            )
        if relationship in self.relationships:
            warnings.warn("Not adding duplicate relationship: " + str(relationship))
            return self

        # _operations?

        # this is a new pair of dataframes
        child_df = relationship.child_dataframe
        child_column = relationship._child_column_name
        if child_df.ww.index == child_column:
            msg = "Unable to add relationship because child column '{}' in '{}' is also its index"
            raise ValueError(msg.format(child_column, child_df.ww.name))
        parent_df = relationship.parent_dataframe
        parent_column = relationship._parent_column_name

        if parent_df.ww.index != parent_column:
            parent_df.ww.set_index(parent_column)

        # Empty dataframes (as a result of accessing metadata)
        # default to object dtypes for categorical columns, but
        # indexes/foreign keys default to ints. In this case, we convert
        # the empty column's type to int
        if (
            child_df.empty
            and child_df[child_column].dtype == object
            and parent_df.ww.columns[parent_column].is_numeric
        ):
            child_df.ww[child_column] = pd.Series(name=child_column, dtype=np.int64)

        parent_ltype = parent_df.ww.logical_types[parent_column]
        child_ltype = child_df.ww.logical_types[child_column]
        if parent_ltype != child_ltype:
            difference_msg = ""
            if str(parent_ltype) == str(child_ltype):
                difference_msg = "There is a conflict between the parameters. "

            warnings.warn(
                f"Logical type {child_ltype} for child column {child_column} does not match "
                f"parent column {parent_column} logical type {parent_ltype}. {difference_msg}"
                "Changing child logical type to match parent.",
            )
            child_df.ww.set_types(logical_types={child_column: parent_ltype})

        if "foreign_key" not in child_df.ww.semantic_tags[child_column]:
            child_df.ww.add_semantic_tags({child_column: "foreign_key"})

        self.relationships.append(relationship)
        self.reset_data_description()
        return self
Add a new relationship between dataframes in the entityset. Relationships can be specified
        by passing dataframe and columns names or by passing a :class:`.Relationship` object.

        Args:
            parent_dataframe_name (str): Name of the parent dataframe in the EntitySet. Must be specified
                if relationship is not.
            parent_column_name (str): Name of the parent column. Must be specified if relationship is not.
            child_dataframe_name (str): Name of the child dataframe in the EntitySet. Must be specified
                if relationship is not.
            child_column_name (str): Name of the child column. Must be specified if relationship is not.
            relationship (Relationship): Instance of new relationship to be added. Must be specified
                if dataframe and column names are not supplied.
        
featuretools/entityset/entityset.py