Store entities and their attributes

        Args:
            df (pandas.DataFrame): data to store (storing appends 'id' and 'type' columns!)
            attribute_columns (list(str)): list of column labels that define attributes

def store(self, df, attribute_columns):
        """Store entities and their attributes

        Args:
            df (pandas.DataFrame): data to store (storing appends 'id' and 'type' columns!)
            attribute_columns (list(str)): list of column labels that define attributes
        """

        # ID start values depend on currently stored entities/attributes!
        entity_id_start = models.Entity.get_max_id(self.session) + 1
        attribute_id_start = models.Attribute.get_max_id(self.session) + 1

        # append ID and type columns
        df['id'] = range(entity_id_start, entity_id_start + len(df))
        df['type'] = self.type

        # store entities
        df[['id', 'type']].to_sql(name=models.Entity.__tablename__,
                                  con=self.client.engine,
                                  if_exists='append',
                                  index=False)

        # store attributes
        for col in attribute_columns:
            # ID column of df is the entity ID of the attribute
            attr_df = df[[col, 'id']].rename(columns={'id': 'entity_id',
                                                      col: 'value'})
            attr_df['name'] = col

            # add entity ID column, need to respect already existing entities
            attr_df['id'] = range(attribute_id_start, attribute_id_start + len(df))
            attribute_id_start += len(df)

            # store
            attr_df.to_sql(name=models.Attribute.__tablename__,
                           con=self.client.engine,
                           if_exists='append',
                           index=False)